Iphone : UITableView Header row repeating after 6 rows - iphone

I am developing a Universal app. In this app there is a UITableView. Problem is that the header row in TableView is repeating after 6 rows in iphone and 9 rows in iPad.
I googled but not find solution to solve this header issue. please help.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [tripList count];
}
UiTableview cellForRowAtIndexPath code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UILabel *lblTripNumber = nil;
UILabel *lblTripState = nil;
UIImageView *imgTripState = nil;
UILabel *lblStateTitleText = nil;
UILabel *lblTripNUmberTitleValue = nil;
static NSUInteger const kTripNumberLabelTag = 2;
static NSUInteger const kTripStateLabelTag = 3;
static NSUInteger const kTripImageTag = 4;
BOOL isiPhone = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(indexPath.row == 0)
{
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
if (!isiPhone) // 1=Ipad
{
lblStateTitleText = [[[UILabel alloc] initWithFrame:CGRectMake(205, 27, 250, (cell.contentView.frame.size.height))] autorelease];
lblStateTitleText.font = [UIFont boldSystemFontOfSize:32];
}
else
{
lblStateTitleText = [[[UILabel alloc] initWithFrame:CGRectMake(65, 10, 130, (cell.contentView.frame.size.height))] autorelease];
lblStateTitleText.font = [UIFont boldSystemFontOfSize:16];
}
lblStateTitleText.textAlignment = UITextAlignmentLeft;
lblStateTitleText.backgroundColor = [UIColor clearColor];
lblStateTitleText.tag = 11;
lblStateTitleText.text = #"Trip State";
lblStateTitleText.textColor = [UIColor cyanColor];
[cell.contentView addSubview:lblStateTitleText];
if (!isiPhone) // 1=Ipad
{
lblTripNUmberTitleValue = [[[UILabel alloc] initWithFrame:CGRectMake(445, 27, 290, (cell.contentView.frame.size.height))] autorelease];
lblTripNUmberTitleValue.font = [UIFont boldSystemFontOfSize:32];
}
else
{
lblTripNUmberTitleValue = [[[UILabel alloc] initWithFrame:CGRectMake(180, 10, 250, (cell.contentView.frame.size.height))] autorelease];
lblTripNUmberTitleValue.font = [UIFont boldSystemFontOfSize:16];
}
lblTripNUmberTitleValue.textAlignment = UITextAlignmentLeft;
lblTripNUmberTitleValue.backgroundColor = [UIColor clearColor];
lblTripNUmberTitleValue.tag = 12;
lblTripNUmberTitleValue.text = #"Confirmation#";
lblTripNUmberTitleValue.textColor = [UIColor greenColor];
[cell.contentView addSubview:lblTripNUmberTitleValue];
}
}
else
{
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
CGFloat xIndex = 6.0;
CGFloat xIpadIndex = 6.0;
CGFloat TripNumberLabelWidth = 130.0;
if (!isiPhone) // 1=Ipad
{
imgTripState = [[[UIImageView alloc] initWithFrame:CGRectMake(xIndex, 18, 50, 64)] autorelease];
}
else
{
imgTripState = [[[UIImageView alloc] initWithFrame:CGRectMake(xIndex, 8, 32, 32)] autorelease];
}
imgTripState.tag = kTripImageTag;
[cell.contentView addSubview:imgTripState];
xIndex +=73;
xIpadIndex +=85;
if (!isiPhone) // 1=Ipad
{
lblTripState = [[[UILabel alloc] initWithFrame:CGRectMake(xIpadIndex, 25, TripNumberLabelWidth, (cell.contentView.frame.size.height))] autorelease];
lblTripState.font = [UIFont boldSystemFontOfSize:38];
}
else
{
lblTripState = [[[UILabel alloc] initWithFrame:CGRectMake(xIndex, 1, TripNumberLabelWidth, (cell.contentView.frame.size.height))] autorelease];
lblTripState.font = [UIFont boldSystemFontOfSize:20];
}
lblTripState.textAlignment = UITextAlignmentLeft;
lblTripState.backgroundColor = [UIColor clearColor];
lblTripState.tag = kTripStateLabelTag;
lblTripState.textColor = [UIColor colorWithRed:(0.0/255) green:(241.0/255) blue:(216.0/255) alpha:1.0f];
[cell.contentView addSubview:lblTripState];
xIndex +=132;
xIpadIndex +=120;
if (!isiPhone) // 1=Ipad
{
lblTripNumber = [[[UILabel alloc] initWithFrame:CGRectMake(xIpadIndex, 25, TripNumberLabelWidth, (cell.contentView.frame.size.height))] autorelease];
lblTripNumber.font = [UIFont boldSystemFontOfSize:35];
}
else
{
lblTripNumber = [[[UILabel alloc] initWithFrame:CGRectMake(xIndex, 0, TripNumberLabelWidth, (cell.contentView.frame.size.height))] autorelease];
lblTripNumber.font = [UIFont boldSystemFontOfSize:18];
}
lblTripNumber.textAlignment = UITextAlignmentLeft;
lblTripNumber.backgroundColor = [UIColor clearColor];
lblTripNumber.tag = kTripNumberLabelTag;
lblTripNumber.textColor = [UIColor greenColor];
[cell.contentView addSubview:lblTripNumber];
}else
{
// A reusable cell was available, so we just need to get a reference to the subviews using their tags.
lblTripNumber = (UILabel *)[cell.contentView viewWithTag:kTripNumberLabelTag];
lblTripState = (UILabel *)[cell.contentView viewWithTag:kTripStateLabelTag];
// imgTripState = (UILabel *)[cell.contentView viewWithTag:kTripImageTag];
}
lblTripNumber.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
lblTripState.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
int indCount = indexPath.row -1;
TripDetails *trip = [tripList objectAtIndex:indCount];
lblTripNumber.text = trip.tripNumber;
lblTripState.text = trip.tripState;
// Configure the cell...
return cell;
}

You probably have only 6 items in your TableData.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [TableData count];
}
In your case 'TableData' is 'tripList'.

I got that , I removed
if (cell == nil)
and it worked fine. Actually it was looking for its tags in first header row and could not replace its values, so was creating problem.

check your viewFor header in section. if you are using array for your header views, then this array object is not properly allocated memory. it uses last object for all it's occurance and replace the old. Make a memory allocated object of array before you add objects to it. tell me if this is the solution

Your code tries to reuse the cells, but the way you coded that is wrong. See my answer here for the appropriate pattern. In a nut shell, you should only define shared cell attributes in if (cell == nil) section, the row specific attributes, like label text etc. should be defined outside of this section. This is not the case for your row at index 0.

Related

UITableViewCell showing double embedded UITextfields

I have a UITableView with regular UITableViewCell, but I don't use any of UITableViewCell's lables. I just use the cell to embed a label and a UITextField to input some data. Problem is when you scroll up or scroll down and the UITableviewCell redraws itself, it draws an overlapping UITextFieldView over the old one and you see doubles! I'm thinking that maybe since I do put these UITextFields into a dictionary, it might save the textfield with a strong pointer, and try to make another one and just overlap. Anyone have any suggestions?
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ProductCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *product = [self.products objectAtIndex:indexPath.row];
NSDictionary *orderpoint = [self.orderpoints objectAtIndex:indexPath.row];
cell.textLabel.text = #""; //black out text
CGFloat calculatedHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath];
UILabel *productLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, cell.bounds.size.width - 50.0, calculatedHeight)];
productLabel.text = [[NSString alloc] initWithFormat:#"%#. %#",
[orderpoint objectForKey:#"sequence_nr"], [product objectForKey:#"name"]];
//word wrapping
productLabel.lineBreakMode = UILineBreakModeWordWrap;
productLabel.numberOfLines = 0; //infinite number of lines
productLabel.font = [UIFont fontWithName:#"Helvetica" size:14.0];
[cell.contentView addSubview:productLabel];
//create the cell's textfield
UITextField *cellTextField = [[UITextField alloc] initWithFrame:CGRectMake(cell.bounds.size.width - 50, cell.bounds.size.height - 30, 50, calculatedHeight - 20)];
cellTextField.adjustsFontSizeToFitWidth = YES;
cellTextField.textColor = [UIColor blackColor];
cellTextField.keyboardType = UIKeyboardTypeNumberPad; // will only need to end a count
cellTextField.returnKeyType = UIReturnKeyDone; // TODO make it go to the next items key, or make it exit out
cellTextField.backgroundColor = [UIColor whiteColor];
cellTextField.textAlignment = UITextAlignmentLeft; //align to the right
//cellTextField.delegate = self; //will need to set delegate, maybe
cellTextField.clearButtonMode = UITextFieldViewModeNever;
cellTextField.enabled = YES;
cellTextField.borderStyle = UITextBorderStyleRoundedRect; //add bezel rounded look to textfield
cellTextField.delegate = self;
[cell.contentView addSubview: cellTextField]; //add the textfield to the cell
// save to dictionary, using a dictionary because not certain if this is created in order to use an Array
[self.textFieldDict setObject:cellTextField forKey:[[NSNumber alloc] initWithInteger:indexPath.row]];
return cell;
}
You have not initialized your cell.Try this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ProductCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//It will check whether cell in there or not, then deque the cell...
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSDictionary *product = [self.products objectAtIndex:indexPath.row];
NSDictionary *orderpoint = [self.orderpoints objectAtIndex:indexPath.row];
cell.textLabel.text = #""; //black out text
CGFloat calculatedHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath];
UILabel *productLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, cell.bounds.size.width - 50.0, calculatedHeight)];
productLabel.text = [[NSString alloc] initWithFormat:#"%#. %#",
[orderpoint objectForKey:#"sequence_nr"], [product objectForKey:#"name"]];
//word wrapping
productLabel.lineBreakMode = UILineBreakModeWordWrap;
productLabel.numberOfLines = 0; //infinite number of lines
productLabel.font = [UIFont fontWithName:#"Helvetica" size:14.0];
[cell.contentView addSubview:productLabel];
//create the cell's textfield
UITextField *cellTextField = [[UITextField alloc] initWithFrame:CGRectMake(cell.bounds.size.width - 50, cell.bounds.size.height - 30, 50, calculatedHeight - 20)];
cellTextField.adjustsFontSizeToFitWidth = YES;
cellTextField.textColor = [UIColor blackColor];
cellTextField.keyboardType = UIKeyboardTypeNumberPad; // will only need to end a count
cellTextField.returnKeyType = UIReturnKeyDone; // TODO make it go to the next items key, or make it exit out
cellTextField.backgroundColor = [UIColor whiteColor];
cellTextField.textAlignment = UITextAlignmentLeft; //align to the right
//cellTextField.delegate = self; //will need to set delegate, maybe
cellTextField.clearButtonMode = UITextFieldViewModeNever;
cellTextField.enabled = YES;
cellTextField.borderStyle = UITextBorderStyleRoundedRect; //add bezel rounded look to textfield
cellTextField.delegate = self;
[cell.contentView addSubview: cellTextField]; //add the textfield to the cell
return cell;
}
Either don't use reusability and always alloc the cell at each time or
make a check after dequeue (like this)
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil)
{
// make text field and label an add tag
}
//and outside this by using tag fetch the labels and textField and clear the textFields.
You forgot to put the condition like this:
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:CellIdentifier];
}
Used this as a reference: add subviews to UITableViewCell
I just first checked to see if this view was added from before, and if it was, then don't add it again. It has nothing to do with the cell being nil. Unless I missed something? all I know is that this seems to be working fine, now.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ProductCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *product = [self.products objectAtIndex:indexPath.row];
NSDictionary *orderpoint = [self.orderpoints objectAtIndex:indexPath.row];
cell.textLabel.text = #""; //black out text
CGFloat calculatedHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath];
UILabel *productLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, cell.bounds.size.width - 50.0, calculatedHeight)];
productLabel.text = [[NSString alloc] initWithFormat:#"%#. %#",
[orderpoint objectForKey:#"sequence_nr"], [product objectForKey:#"name"]];
//word wrapping
productLabel.lineBreakMode = UILineBreakModeWordWrap;
productLabel.numberOfLines = 0; //infinite number of lines
productLabel.font = [UIFont fontWithName:#"Helvetica" size:14.0];
[cell.contentView addSubview:productLabel];
if (![cell viewWithTag:1])
{
//create the cell's textfield
UITextField *cellTextField = [[UITextField alloc] initWithFrame:CGRectMake(cell.bounds.size.width - 50, cell.bounds.size.height - 30, 50, calculatedHeight - 20)];
cellTextField.adjustsFontSizeToFitWidth = YES;
cellTextField.textColor = [UIColor blackColor];
cellTextField.keyboardType = UIKeyboardTypeNumberPad; // will only need to end a count
cellTextField.returnKeyType = UIReturnKeyDone; // TODO make it go to the next items key, or make it exit out
cellTextField.backgroundColor = [UIColor whiteColor];
cellTextField.textAlignment = UITextAlignmentLeft; //align to the right
cellTextField.delegate = self; //will need to set delegate, maybe
cellTextField.clearButtonMode = UITextFieldViewModeNever;
cellTextField.enabled = YES;
cellTextField.borderStyle = UITextBorderStyleRoundedRect; //add bezel rounded look to textfield
cellTextField.delegate = self;
cellTextField.tag = 1; //set tag to 1
[cell.contentView addSubview: cellTextField]; //add the textfield to the cell
// save to dictionary, using a dictionary because not certain if this is created in order to use an Array
[self.textFieldDict setObject:cellTextField forKey:[[NSNumber alloc] initWithInteger:indexPath.row]];
}
return cell;
}

UILabel overlapping in UITableViewCell

I have a 2x UILabels, 1 title 1 subtitle,
Which are meant to change when a segmentedControl is selected.
It works but instead i get the SAME UILabel overlapping itself when a different segment is selected?
I think i need to create an action to remove the label from the superview before it is redisplayed onto the cell? just wondering how to go about it
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
EventUpcoming *aEventUpcoming = [euEvent objectAtIndex:indexPath.section];
EventWeekly *aEventWeekly = [ewEvent objectAtIndex:indexPath.section];
UILabel *cellTitle = [[UILabel alloc] initWithFrame:CGRectMake(15, 5, 290, 20)];
UILabel *cellSubtitle = [[UILabel alloc] initWithFrame:CGRectMake(15, 20, 290, 20)];
NSString *titleString = [[NSString alloc] init];
NSString *subtitleString = [[NSString alloc] init];
if (segmentedControl.selectedSegmentIndex == 0)
{
Event *aEvent = [aEventUpcoming.event objectAtIndex:indexPath.row];
titleString = aEvent.name;
subtitleString = aEvent.subtitle;
}
else
{
Event *aEvent = [aEventWeekly.event objectAtIndex:indexPath.row];
titleString = aEvent.name;
subtitleString = aEvent.subtitle;
}
NSString *titleStringUC = [titleString uppercaseString];
NSString *subtitleStringLC = [subtitleString lowercaseString];
cellTitle.text = titleStringUC;
cellTitle.font = [UIFont boldSystemFontOfSize:11];
cellTitle.textColor = [UIColor colorWithRed:142/255.0f green:142/255.0f blue:142/255.0f alpha:1];
cellTitle.shadowColor = [UIColor whiteColor];
cellTitle.shadowOffset = CGSizeMake(1, 1);
cellTitle.backgroundColor = [UIColor clearColor];
cellSubtitle.text = subtitleStringLC;
cellSubtitle.font = [UIFont boldSystemFontOfSize:11];
cellSubtitle.textColor = [UIColor colorWithRed:177/255.0f green:177/255.0f blue:177/255.0f alpha:1];
cellSubtitle.shadowColor = [UIColor whiteColor];
cellSubtitle.shadowOffset = CGSizeMake(1, 1);
cellSubtitle.backgroundColor = [UIColor clearColor];
tableViewCellSeparator = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"TableCellSeparator.png"]];
tableViewCellSeparator.frame = CGRectMake(0, cell.bounds.size.height - 2, 320, 2);
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
[cell.contentView addSubview:cellTitle];
[cell.contentView addSubview:cellSubtitle];
[cell.contentView addSubview:tableViewCellSeparator];
return cell;
}
UPDATE:
Both were very valid answers, tyvm
You're not reusing your cell correctly, so you're not getting the performance benefit of reuse, and making the code more complicated. You're also not using the pieces that Apple gives you to work with out of the box.
First, you should create and add all your subviews inside the cell==nil block. This is where you create your reusable cell. In the rest of the routine, you're just reconfiguring the cell. This is much, much faster.
Second, UITableViewCell already has two labels built-in. You don't need to create them. They're called textLabel and detailTextLabel. They're normal labels; you can move them around and make them look like whatever you want. Do that in the cell==nil block.
Then you just need to call cell.textLabel.text = ... and cell.detailTextLabel.text = ... outside the cell==nil block and you're good to go.
If you needed more labels than two, then I would subclass UITableViewCell and create new properties on it so that you can easily reconfigure the cell.
I hope it will work now.Try this.....
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
EventUpcoming *aEventUpcoming = [euEvent objectAtIndex:indexPath.section];
EventWeekly *aEventWeekly = [ewEvent objectAtIndex:indexPath.section];
UILabel *cellTitle = [[UILabel alloc] initWithFrame:CGRectMake(15, 5, 290, 20)];
UILabel *cellSubtitle = [[UILabel alloc] initWithFrame:CGRectMake(15, 20, 290, 20)];
NSString *titleString = [[NSString alloc] init];
NSString *subtitleString = [[NSString alloc] init];
NSString *titleStringUC = [titleString uppercaseString];
NSString *subtitleStringLC = [subtitleString lowercaseString];
cellTitle.text = titleStringUC;
cellTitle.font = [UIFont boldSystemFontOfSize:11];
cellTitle.textColor = [UIColor colorWithRed:142/255.0f green:142/255.0f blue:142/255.0f alpha:1];
cellTitle.shadowColor = [UIColor whiteColor];
cellTitle.shadowOffset = CGSizeMake(1, 1);
cellTitle.backgroundColor = [UIColor clearColor];
cellTitle.tag = 10;
cellSubtitle.text = subtitleStringLC;
cellSubtitle.font = [UIFont boldSystemFontOfSize:11];
cellSubtitle.textColor = [UIColor colorWithRed:177/255.0f green:177/255.0f blue:177/255.0f alpha:1];
cellSubtitle.shadowColor = [UIColor whiteColor];
cellSubtitle.shadowOffset = CGSizeMake(1, 1);
cellSubtitle.backgroundColor = [UIColor clearColor];
cellSubtitle.tag = 11;
tableViewCellSeparator = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"TableCellSeparator.png"]];
tableViewCellSeparator.frame = CGRectMake(0, cell.bounds.size.height - 2, 320, 2);
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
[cell.contentView addSubview:cellTitle];
[cell.contentView addSubview:cellSubtitle];
[cell.contentView addSubview:tableViewCellSeparator];
}
cellTitle = (UILabel *)[cell.contentView viewWithTag:10];
cellSubtitle = (UILabel *)[cell.contentView viewWithTag:11];
if (segmentedControl.selectedSegmentIndex == 0)
{
Event *aEvent = [aEventUpcoming.event objectAtIndex:indexPath.row];
titleString = aEvent.name;
subtitleString = aEvent.subtitle;
}
else
{
Event *aEvent = [aEventWeekly.event objectAtIndex:indexPath.row];
titleString = aEvent.name;
subtitleString = aEvent.subtitle;
}
return cell;
}

UITableview sections overwrite in iPhone?

I have one problem with two sections in UITableview grouped style. First section having 6 rows and second section having 3 rows. When i scroll the tableview up and down the last row content of section 2 is adding in first section first row and the first row content in first section is adding in last row of second section. I check my level best whether the cell become empty to load the content but, it is not happening while debugging. My code is ,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.backgroundColor = [UIColor whiteColor];
if (indexPath.section == 0 && indexPath.row == 0)
{
UILabel *Nameabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, 140, 30)];
Nameabel.text = #"Name";
Nameabel.font = [UIFont fontWithName:#"Helvetica" size:15];
Nameabel.backgroundColor = [UIColor clearColor];
Nameabel.font = [UIFont boldSystemFontOfSize:15];
[cell.contentView addSubview:Nameabel];
textField = [[UITextField alloc] initWithFrame:CGRectMake(145, 5, 150, 30)];
textField.placeholder = #"Student Name";
textField.borderStyle = UITextBorderStyleNone;
textField.font = [UIFont fontWithName:#"Helvetica" size:14];
[cell.contentView addSubview:paymentCatTextField];
}
else if (indexPath.section == 1 && indexPath.row == 0)
{
UILabel *RLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, 140, 30)];
RLabel.text = #"Class";
RLabel.backgroundColor = [UIColor clearColor];
RLabel.font = [UIFont fontWithName:#"Helvetica" size:15];
RLabel.font = [UIFont boldSystemFontOfSize:15];
[cell.contentView RLabel];
RTextField = [[UITextField alloc] initWithFrame:CGRectMake(145, 5, 150, 30)];
RTextField.placeholder = #"class Name";
RTextField.borderStyle = UITextBorderStyleNone;
RTextField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
RTextField.font = [UIFont fontWithName:#"Helvetica" size:14];
[cell.contentView addSubview:RTextField];
}
}
return cell;
}
This is for sample. By this way the section 0 have 6 rows and section 1 have 3 rows. Where i am doing wrong. Please help my to solve this problem.
Thanks in advance.
Change your code to the following and try again:
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.backgroundColor = [UIColor whiteColor];
}
if (indexPath.section == 0 && indexPath.row == 0) {
//bla bla
} else if (indexPath.section == 1 && indexPath.row == 0) {
//bla bla
}
return cell;
}
The reason is that you are setting the cell content only when you are not reusing the cell. That's wrong in most cases.
In addition to dasdom's answer I would also suggest removing the subviews before adding the labels.
if ([[cell.contentView subviews] count] > 0) {
UIView *labelToClear = [[cell.contentView subviews] objectAtIndex:0];
[labelToClear removeFromSuperview];
UIView *textToClear = [[cell.contentView subviews] objectAtIndex:1];
[textToClear removeFromSuperview];
}
and autoreleasing the subviews:
UILabel *Nameabel = [[[UILabel alloc] initWithFrame:CGRectMake(5, 5, 140, 30)] autorelease];
UITextField *textField = [[[UITextField alloc] initWithFrame:CGRectMake(145, 5, 150, 30)] autorelease];

Problem adding UITableViewCell manually

I am trying to add a UITableViewCell at the very bottom of my UITableView programatically. I am getting an index out of bounds error, which I am not sure how to resolve:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [items count]+1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
if (indexPath.row == [items count] + 1) {
UITableViewCell* cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MoreCell"] autorelease];
cell.textLabel.text = #"More...";
return cell;
}
else {
STUser *mySTUser;
mySTUser = [items objectAtIndex:indexPath.row]; //!!INDEX OUT OF BOUNDS HERE!!
AsyncImageView* asyncImage = nil;
UILabel* loginLabel = nil;
UILabel* fullNameLabel = nil;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
CGRect frame = CGRectMake(0, 0, 44, 44);
CGRect loginLabelFrame = CGRectMake(60, 0, 200, 10);
CGRect fullNameLabelFrame = CGRectMake(60, 20, 200, 10);
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:nil] autorelease];
asyncImage = [[[AsyncImageView alloc]initWithFrame:frame] autorelease];
[cell.contentView addSubview:asyncImage];
loginLabel = [[[UILabel alloc] initWithFrame:loginLabelFrame] autorelease];
[cell.contentView addSubview:loginLabel];
fullNameLabel = [[[UILabel alloc] initWithFrame:fullNameLabelFrame] autorelease];
[cell.contentView addSubview:fullNameLabel];
asyncImage.tag = IMAGE_TAG;
loginLabel.tag = LOGIN_TAG;
fullNameLabel.tag = FULL_NAME_TAG;
}
else {
asyncImage = (AsyncImageView *) [cell.contentView viewWithTag:IMAGE_TAG];
loginLabel = (UILabel *) [cell.contentView viewWithTag:LOGIN_TAG];
fullNameLabel = (UILabel *) [cell.contentView viewWithTag:FULL_NAME_TAG];
}
// Configure the cell...
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
CGRect frame = CGRectMake(0, 0, 44, 44);
asyncImage = [[[AsyncImageView alloc]initWithFrame:frame] autorelease];
NSURL* url = [NSURL URLWithString:mySTUser.avatar_url_large];
[asyncImage loadImageFromURL:url];
asyncImage.tag = IMAGE_TAG;
[cell.contentView addSubview:asyncImage];
CALayer * l = [asyncImage layer];
[l setMasksToBounds:YES];
[l setCornerRadius:5.0];
CGRect loginLabelFrame = CGRectMake(60, 0, 200, 20);
loginLabel = [[[UILabel alloc] initWithFrame:loginLabelFrame] autorelease];
loginLabel.text = [NSString stringWithFormat:#"%#",mySTUser.login];
loginLabel.tag = LOGIN_TAG;
[cell.contentView addSubview:loginLabel];
CGRect fullNameLabelFrame = CGRectMake(60, 20, 200, 20);
fullNameLabel = [[[UILabel alloc] initWithFrame:fullNameLabelFrame] autorelease];
fullNameLabel.text = [NSString stringWithFormat:#"%# %#",mySTUser.first_name, mySTUser.last_name];
fullNameLabel.tag = FULL_NAME_TAG;
fullNameLabel.font = [UIFont fontWithName:#"Helvetica" size:(12.0)];
[cell.contentView addSubview:fullNameLabel];
return cell;
}
}
If the count is items + 1 I want to return the More Cell, if not, then I want it to create all of the other cells. Not sure why I get the index out of bounds since the code should never reach that point.
indexPath.row is zero based.
Change:
if (indexPath.row == [items count] + 1) {
To:
if (indexPath.row == [items count]) {
Arrays in Objective-C and almost all other programming languages are zero-based. That means the first object has index 0, and the last object has index (length - 1).
Therefore, the condition
if (indexPath.row == [items count] + 1) {
should be changed to
if (indexPath.row == [items count]) {

custom cell based on row index iphone

I'm wondering if it is possible to add cell content to a uitableview based on the row index?
For example if it is the first cell (row 0) I want to add an image and text.
If it is the second row I would like to add a button.
For all other rows I would like to just add a line of text.
I tried using indexPath.row. It worked the first time but when I scroll off of the screen and then back up my first image dissapears.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
PromoListItem *promo = [promoList objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"Cell";
AsyncImageView *asyncImageView = nil;
UILabel *label = nil;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(indexPath.row==0)
{
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
CGRect frame;
frame.origin.x = 0;
frame.origin.y = 0;
frame.size.width = 100;
frame.size.height = 100;
asyncImageView = [[[AsyncImageView alloc] initWithFrame:frame] autorelease];
asyncImageView.tag = ASYNC_IMAGE_TAG;
[cell.contentView addSubview:asyncImageView];
frame.origin.x = 110;
frame.size.width =100;
label = [[[UILabel alloc] initWithFrame:frame] autorelease];
label.tag = LABEL_TAG;
[cell.contentView addSubview:label];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
} else {
asyncImageView = (AsyncImageView *) [cell.contentView viewWithTag:ASYNC_IMAGE_TAG];
label = (UILabel *) [cell.contentView viewWithTag:LABEL_TAG];
}
NSURL *url = [NSURL URLWithString:promo.imgurl];
[asyncImageView loadImageFromURL:url];
label.text = promo.artistname;
}else
{
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
CGRect frame;
frame.origin.x = 0;
frame.origin.y = 0;
frame.size.width = 100;
frame.size.height = 100;
//asyncImageView = [[[AsyncImageView alloc] initWithFrame:frame] autorelease];
// asyncImageView.tag = ASYNC_IMAGE_TAG;
// [cell.contentView addSubview:asyncImageView];
frame.origin.x = 110;
frame.size.width =100;
label = [[[UILabel alloc] initWithFrame:frame] autorelease];
label.tag = LABEL_TAG;
[cell.contentView addSubview:label];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
} else {
// asyncImageView = (AsyncImageView *) [cell.contentView viewWithTag:ASYNC_IMAGE_TAG];
label = (UILabel *) [cell.contentView viewWithTag:LABEL_TAG];
}
//NSURL *url = [NSURL URLWithString:promo.imgurl];
//[asyncImageView loadImageFromURL:url];
label.text = promo.artistname;
}
return cell;
}
How customized do you want these cells? If you are only adding text, images and accessory buttons, you can create the cell outside of your row check, and then add the needed items inside those if statements.
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
NSUInteger row = [indexPath row];
switch(row) {
case 0:
cell.textLabel.text = #"row 0";
cell.image
break;
case 1:
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
break;
default:
cell.textLabel.text = [NSString stringWithFormat:#"row %d",row];
break;
}
return cell;
However, the row will change when you start to recycle your cells, you may want to have something in the actual data that indicates how the cell should behave.