Custom components to cells in Table - ios

How do i add different componenets to different cells in a tableview. Please note that this is a static table and i have only 4 cells.
The first cell will have an UIImageView.
The other 3 cells will just have labels or textfieilds.
How can i add these components.
Note: This is a storyboard based application and i have added
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyTableViewCell *cell;
if(indexPath.row == 0)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell0"];
cell.profImageView.image=[UIImage imageNamed:#"m.jpg"];
return cell;
}
else if(indexPath.row == 1)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell1"];
cell.lbl.text=#"Hey";
return cell;
}
else if(indexPath.row == 2)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell2"];
cell.lbl.text=#"Hey 2";
return cell;
}
return cell;
}

You are having 4 rows in your data source but you are only providing cell object for 3 rows. The last return statement will execute for indexPath.row==3 and you have not initialised it. Just initialise it for indexPath.row==3 and you are good to go.

MyTableViewCell *cell;
if(indexPath.row == 0)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell0"];
cell.profImageView.image=[UIImage imageNamed:#"m.jpg"];
}
else if(indexPath.row == 1)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell1"];
cell.lbl.text=#"Hey";
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell2"];
cell.lbl.text=#"Hey 2";
}
return cell;
The reason that you don't give the default return value to your function and it asks for "If everything goes wrong what will i return?". So you may fix your codes like above and you can try to make like below with the switch - case.
TableViewCell *cell;
switch (indexPath.row) {
case 0:{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell0"];
cell.imageView.image=[UIImage imageNamed:#"m.jpg"];
}break;
case 1:{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell1"];
cell.myLabel.text=#"Hey";
}break;
case 2:{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell2"];
cell.myLabel.text=#"Hey 2";
}break;
default:{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell0"];
cell.imageView.image=[UIImage imageNamed:#"m.jpg"];
}
break;
}
return cell;
In above switch-case you may call which cell you want in default statement.

Related

expanded UITableviewCell height not manageable

I am using this in my app and i am create two identifiers for UITableview one is "normal cell" and another one is "expended cell" which will show when someone tap on a "normal cell". my problem is this that I can not manage heights of both cells separately for example I want normal cell height to be 120 and extended cell is to be 60. But if I change height in heightForRowAtIndexPath then both cells showing same height. here is my code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FSParallaxTableViewCell *cell = nil;
static NSString *cellIdentifier = nil;
if ([indexPath isEqual:self.expandedIndexPath]) {
cellIdentifier = #"ExpandedCell";
}
else {
cellIdentifier = #"NormalCell";
}
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[FSParallaxTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
if ([[cell reuseIdentifier] isEqualToString:#"ExpandedCell"]) {
cell.contentView.backgroundColor = [UIColor grayColor];
}
if ([[cell reuseIdentifier] isEqualToString:#"NormalCell"]) {
[cell.cellImageView sd_setImageWithURL:[NSURL URLWithString:[[rssOutputData objectAtIndex:indexPath.row]xmllink]]
placeholderImage:[UIImage imageNamed:#"placeholder"] options:indexPath.row == 0 ? SDWebImageRefreshCached : 0];
cell.clipsToBounds = YES;
}
return cell;
}
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// disable touch on expanded cell
UITableViewCell *cell = [self.theTableView cellForRowAtIndexPath:indexPath];
if ([[cell reuseIdentifier] isEqualToString:#"ExpandedCell"]) {
return;
}
// deselect row
[tableView deselectRowAtIndexPath:indexPath
animated:NO];
// get the actual index path
indexPath = [self actualIndexPathForTappedIndexPath:indexPath];
// save the expanded cell to delete it later
NSIndexPath *theExpandedIndexPath = self.expandedIndexPath;
// same row tapped twice - get rid of the expanded cell
if ([indexPath isEqual:self.expandingIndexPath]) {
self.expandingIndexPath = nil;
self.expandedIndexPath = nil;
}
// add the expanded cell
else {
self.expandingIndexPath = indexPath;
self.expandedIndexPath = [NSIndexPath indexPathForRow:[indexPath row] + 1
inSection:[indexPath section]];
}
[tableView beginUpdates];
if (theExpandedIndexPath) {
[theTableView deleteRowsAtIndexPaths:#[theExpandedIndexPath]
withRowAnimation:UITableViewRowAnimationNone];
}
if (self.expandedIndexPath) {
[theTableView insertRowsAtIndexPaths:#[self.expandedIndexPath]
withRowAnimation:UITableViewRowAnimationNone];
}
[tableView endUpdates];
// scroll to the expanded cell
[self.theTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle
animated:YES];
}
can anyone please help me resolving this issue I want to set height for both cells separately.
add below code in heightForAtIndexpath method
if ([indexPath isEqual:self.expandedIndexPath]) {
return 60.0;
}
else
return 120.0f;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
}
if ([[cell reuseIdentifier] isEqualToString:#"ExpandedCell"]) {
return 60;
}
if ([[cell reuseIdentifier] isEqualToString:#"NormalCell"]) {
return 120;
}
}
You have to set the height of table view cell separately. you can set the height separately according as the row.In following code i have set the 1st row height 35, 2nd row height 70 and rest of the row will have height 65.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.row)
{
case 0:
return 35;
break;
case 1:
return 70;
break;
default:
return 65;
break;
}
}

Changing the default TableViewCell to custom subclass on button click

In a specific row I apply the default UITableViewCell class with a text label and an accessory button. When the accessory button is clicked, the cell is expanded and I want to change the UITableViewCell to a custom subclass I have created. However even if the cell is expanded, it won't switch to the custom subclass. Any ideas what to fix?
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat result;
switch ([indexPath row])
{
case 2:
{
if ([indexPath isEqual:expandedRow]) {
return 100;
} else {
return 42;
}
}
return result;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier;
NSString *CellIdentifierexp;
UITableViewCell *cell;
if (cell == nil) {
if (indexPath.row == 2) {
if ([indexPath isEqual:expandedRow]) {
cell = [[ExpandedCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierexp];
}else{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
switch ([indexPath row])
{
case 2:
{
if ([indexPath isEqual:expandedRow]) {
NSLog(#"bike");
ExpandedCell *expandedcell = (ExpandedCell *)cell;
[expandedcell.text setText:self.descr];
NSArray *indexPathArray=[NSArray arrayWithObject:indexPath];
[self.tableview reloadRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationNone];
} else {
cell.textLabel.text = #"Description";
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.textColor = UIColorFromRGB(0x2d5b3b);
// accessory type image
UIImage *image = [UIImage imageNamed:#"greenarrow.jpg"]; //or wherever you take your image from
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(0,0, image.size.width, image.size.height)];
[button setBackgroundImage:image forState:UIControlStateNormal];
[button addTarget:self action:#selector(accessoryButtonTapped:withEvent:) forControlEvents:UIControlEventTouchDown];
button.userInteractionEnabled = YES;
cell.accessoryView = button;
}
break;
}
return cell;
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
switch ([indexPath row])
{
case 2:
{
NSLog(#"Detail Disclosure Tapped");
expandedRow = indexPath;
[tableview beginUpdates];
[tableview endUpdates];
}
}
}
- (void) accessoryButtonTapped: (UIControl *) button withEvent: (UIEvent *) event
{
NSIndexPath * indexPath = [self.tableview indexPathForRowAtPoint: [[[event touchesForView: button] anyObject] locationInView: tableview]];
if ( indexPath == nil )
return;
[self.tableview.delegate tableView: self.tableview accessoryButtonTappedForRowWithIndexPath: indexPath];
}
Wow, you're doing something terribly wrong in here:
ExpandedCell *expandedcell = (ExpandedCell *)cell;
[expandedcell.text setText:self.descr];
NSArray *indexPathArray=[NSArray arrayWithObject:indexPath];
[self.tableview reloadRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationNone];
What you should do is slightly different. On a button tap you just call the [self.tableview reloadRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationNone]; then in the cellForRowAtIndexPath you should return the custom cell of your subclass in the method if the indexPath matches. No need to update the tableView there.
And need I say that this looks like a very very strange switch statement to me:
switch ([indexPath row])
{
case 2:
{
NSLog(#"Detail Disclosure Tapped");
expandedRow = indexPath;
[tableview beginUpdates];
[tableview endUpdates];
}
}
I would simply put it like this:
if (indexPath.row == 2){
NSLog(#"Detail Disclosure Tapped");
expandedRow = indexPath;
[tableview beginUpdates];
[self.tableview reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableview endUpdates];
}
Running the code
expandedRow = indexPath;
[tableview beginUpdates];
[tableview endUpdates];
when the accessory button is tapped will only ask the table view to update the row heights, it won't actually request a new cell for any row, so no cell type change will happen (until you scroll the row off screen and then back on again).
So, you need to actually reload the selected row, not just begin and end updates.
this here...
UITableViewCell *cell;
if (cell == nil) {
Local vars dont init to nil , they start as garbage, maybe nil , maybe not.
Either way you probably are not making it into the branch.
You are going to want to dequeue a cell from the table depending on whether its an expanded row or not
UITableViewCell *cell = nil;
if(thisIsAnExpandedRow) {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierexp];
if(!cell) {
cell = [[ExpandedCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierexp];
}
}
else {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
}

How to work with two different custom cells in one tableView ? Using Storyboard, iOS 7

I have two custom cells. And I want to display 2 sections in my UITableView. The first section with one row displaying the first custom cell, and the second section displaying a list of objects pulled from core data.
How should I implement the "cellForRowAtIndexpath" method ?
Here is some of my code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (section == 0) {
return 1;
} else if (section == 1) {
//gastos is an array
return [self.gastos count];
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section) {
case 0:
{
SaldoCelda *cell1 = [tableView dequeueReusableCellWithIdentifier:#"Cell1" forIndexPath:indexPath];
return cell1;
}
case 1:
{
static NSString *CellIdentifier = #"Cell";
CeldaGasto *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSManagedObject *gasto = [self.gastos objectAtIndex:indexPath.row];
[cell.monto setText:[NSString stringWithFormat:#"%# AR$", [gasto valueForKey:#"monto"]]];
[cell.categoria setText:[NSString stringWithFormat:#"%#", [gasto valueForKey:#"categoria"]]];
[cell.fecha setText:[NSString stringWithFormat:#"%#", [gasto valueForKey:#"fecha"]]];
return cell;
}
default:
break;
}
return 0;
}
And this is the error message I get:
Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2903.23/UITableView.m:6246
2014-03-05 01:02:57.181 Spendings[2897:70b] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
Thankyou for your help!
I have made a test and it works fine. These are the steps:
Create UITableViewController in storyBoard
Drag and drop UITableViewCell on a UITableViewController below the cell that is already there
Assign CellIdentifier to both cells (I used Cell1 and Cell2)
Create 2 subclasses of UITableViewCell (I called them Cell1 and Cell2)
Create subclass of UITableViewController and name it somehow
in cellForRowAtIndexPath method:
static NSString *CellIdentifier = #"Cell1";
static NSString *CellIdentifier1 = #"Cell2";
switch (indexPath.section) {
case 0:
{
Cell1 *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
break;
case 1:
{
Cell2 *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1 forIndexPath:indexPath];
return cell;
}
break;
default:
break;
}
return nil;
As you can see the implementation is the same as yours
The only way I could reproduce your error is by returning nil in switch block and the documentation for dequeueReusableCellWithIdentifier says:
This method always returns a valid cell.
Even if you messed up your cell identifiers, you still wouldn't get the error you posted. So my conclusion is:
reboot, clean project, restart simulator or something like that cause your scenario according to documentation is not possible...
Beside you are returning nil for one of your cells, you also has an issue in numberOfRowsInSection, you are returning 0 rows for section 1!!, although you are expecting rows in this section in your cellForRowAtIndexPath.
you can create set of cell in one xib and fetch it in cellForRowAtindex with it's identifier. Now you can set it's property and data to it.
static NSString *CellIdentifier = #"MyCellIdentifier";
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = (MyCell *)[nib objectAtIndex:0];
cell1=(MyCell *)[nib objectAtIndex:1];
}
Try This i'm modifying your code
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (section == 0) {
return 1;
}
else if (section == 2) {
//gastos is an array
return [self.gastos count];
}
//return 0; you should not write this because at the end of execution of this method it will return 0
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
switch (indexPath.section) {
case 0:
{
SaldoCelda *cell1 = [tableView dequeueReusableCellWithIdentifier:#"Cell1" forIndexPath:indexPath];
cell=cell1;
break;
}
case 1:
{
static NSString *CellIdentifier = #"Cell";
CeldaGasto *cell2 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSManagedObject *gasto = [self.gastos objectAtIndex:indexPath.row];
[cell.monto setText:[NSString stringWithFormat:#"%# AR$", [gasto valueForKey:#"monto"]]];
[cell.categoria setText:[NSString stringWithFormat:#"%#", [gasto valueForKey:#"categoria"]]];
[cell.fecha setText:[NSString stringWithFormat:#"%#", [gasto valueForKey:#"fecha"]]];
cell=cell2;
break;
}
default:
break;
}
return cell;
//return 0; remove this in your code
}
Hope this will help

Multiple UITableViewCells different fields per row

I have 2 tableViews, the first only loads a list from an array.
The other 1, show details per row. But it shows a crash report:
'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath: Exception'
What seems to be wrong with my code? I want to show each row a different detail that came from the same sqlite row.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
//tableView 1
if(tableView == self.cTableLabel)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"courseCell"];
NSLog(#"Here.");
Course *courses = [self.course objectAtIndex:indexPath.row];
cell.textLabel.text =courses.cName;
cell.detailTextLabel.text =courses.cSchool;
return cell;
}
//tableView 2
if(tableView == self.jTableLabel)
{
if (indexPath.row == 0)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"JobName"];
cell.textLabel.text = _jDetails.jName;
}
else if (indexPath.row == 1)
{
cell= [tableView dequeueReusableCellWithIdentifier:#"JobEarnings"];
cell.textLabel.text = #"Job Earnings (per month): Php";
cell.detailTextLabel.text = _jDetails.jEarnings;
}
return cell;
}
return 0;
}
For performance reasons, a table view's data source should generally reuse UITableViewCell objects when it assigns cells to rows in its tableView:cellForRowAtIndexPath: method. A table view maintains a queue or list of UITableViewCell objects that the data source has marked for reuse. Call this method from your data source object when asked to provide a new cell for the table view. This method dequeues an existing cell if one is available or creates a new one using the class or nib file you previously registered. If no cell is available for reuse and you did not register a class or nib file, this method returns nil.
If you registered a class for the specified identifier and a new cell must be created, this method initializes the cell by calling its initWithStyle:reuseIdentifier: method. For nib-based cells, this method loads the cell object from the provided nib file. If an existing cell was available for reuse, this method calls the cell’s prepareForReuse method instead.
You need to create different cells for each tableview, Try to use the above code:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell;
//tableView 1
if(tableView == self.cTableLabel)
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
else
{
for(UIView *view in cell.contentView.subviews)
{
[view removeFromSuperview];
}
}
NSLog(#"Here.");
Course *courses = [self.course objectAtIndex:indexPath.row];
cell.textLabel.text =courses.cName;
cell.detailTextLabel.text =courses.cSchool;
return cell;
}
//tableView 2
if(tableView == self.jTableLabel)
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
else
{
for(UIView *view in cell.contentView.subviews)
{
[view removeFromSuperview];
}
}
if (indexPath.row == 0)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"JobName"];
cell.textLabel.text = _jDetails.jName;
}
else if (indexPath.row == 1)
{
cell= [tableView dequeueReusableCellWithIdentifier:#"JobEarnings"];
cell.textLabel.text = #"Job Earnings (per month): Php";
cell.detailTextLabel.text = _jDetails.jEarnings;
}
return cell;
}
return 0;
}
Please cross check either one of your table is returning more number of rows in numberOfRowsInSection method . It might be that you haven't put check on this method as both of the table are returning different number of rows .
First, check that your numberOfRowsInSection returns the correct number of rows for your table. I would think this would be it.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(tableView == self.cTableLabel)
{
return [self.course count];
}
//tableView 2
if(tableView == self.jTableLabel)
{
return 2;
}
return 0;
}
Otherwise I would set a break point on return 0; or NSLog before it in cellForRowAtIndexPath, because my guess is neither if block is hit and you are returning zero. Does it get triggered?
Edit - Ah, I think I see dequeueReusableCellWithIdentifier: will return a nil cell if you haven't set one up yet. Try using dequeueReusableCellWithIdentifier: forIndexPath: instead. This will always return a valid cell assuming you called registerClass:[UITableViewCell class] forCellReuseIdentifier: first.
Give this a shot:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"courseCell"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"JobName"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"JobEarnings"];
//tableView 1
if(tableView == self.cTableLabel)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"courseCell" forIndexPath:indexPath];
NSLog(#"Here.");
Course *courses = [self.course objectAtIndex:indexPath.row];
cell.textLabel.text =courses.cName;
cell.detailTextLabel.text =courses.cSchool;
return cell;
}
//tableView 2
if(tableView == self.jTableLabel)
{
if (indexPath.row == 0)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"JobName" forIndexPath:indexPath];
cell.textLabel.text = _jDetails.jName;
}
else if (indexPath.row == 1)
{
cell= [tableView dequeueReusableCellWithIdentifier:#"JobEarnings" forIndexPath:indexPath];
cell.textLabel.text = #"Job Earnings (per month): Php";
cell.detailTextLabel.text = _jDetails.jEarnings;
}
return cell;
}
return 0;
}
Also registerClass:[UITableViewCell class] forCellReuseIdentifier: could be called in your init, it only needs to be declared once.

TableView with multiple prototype cells

I had a simple question regarding a table view with 3 different kinds of prototype cells. The first two occur just once while the third occurs 4 times. Now what I'm confused about is how to specify in my cellforRowatindexpath which cell prototype to use for which row. So, I want something like for row 0, use prototype 1, for row 1, use prototype 2, for rows 3,4,5 and 6 use prototype 3. What's the best way to do this? Do i give each prototype an identifier and then use dequeueReusableCellWithIdentifier:CellIdentifier ?
Can you'll provide some sample code?
EDIT:
Still not working. This is the code I have at the moment. ( I only have one case for the switch statment because I just want to test and see if the cell is being generated in the first row or not, but currently table view is blank)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
switch(indexPath.row)
{
case 0: {static NSString *CellIdentifier = #"ACell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:#"ACell"];
if(cell==nil) {
cell=[[UITableViewCell alloc]
initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:#"ACell"];
}
return cell;
break;
}
}
}
Acell is my identifier for a cell prototype that I created. I
If you are using three prototype then use three identifiers. Because only one identifier will cause problem. And you will get wrong result. So code like this.
if(indexPath.row==0){
// Create first cell
}
if(indexPath.row==1){
// Create second cell
}
else{
// Create all others
}
You can use switch case also here for best performance.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell.tag == 0)
{
return array1.count;
}
else(cell.tag == 1)
{
return array2.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier;
NSString *membershipType = [membershipTypeArray objectAtIndex:indexPath.row];
if ([membershipType isEqualToString:#"silver"]||[membershipType isEqualToString:#"gold"])
{
cellIdentifier = #"cell";
}
else if ([membershipType isEqualToString:#"platinum"])
{
cellIdentifier = #"premiumCustomCell";
cell.customCellImageView.image = [cellImageArray objectAtIndex:indexPath.row];
}
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.headingLabel.text = [titleArray objectAtIndex:indexPath.row];
}
Here i wrote code like:
#pragma mark == Tableview Datasource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger nRows = 0;
switch (section) {
case 0:
nRows = shipData.count;
break;
case 1:
nRows = dataArray1.count;
break;
default:
break;
}
return nRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *cellIdentifier = #"cellIdentifier1";
NSString *cellIdentifier1 = #"cellIdentifier2";
SingleShippingDetailsCell *cell;
switch (indexPath.section) {
case 0:
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
//Load data in this prototype cell
break;
case 1:
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier1];
//Load data in this prototype cell
break;
default:
break;
}
return cell;
}

Resources