I'm a newbie. I am using this code to create a UITableViewCell but when I reload the table the button's image is not always correct, although all labels work fine. I don't know why. How can I fix this issue?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
UILabel *FileNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 30)];
FileNameLabel.tag = 1000;
FileNameLabel.backgroundColor = [UIColor clearColor];
FileNameLabel.font = [UIFont fontWithName:#"Helvetica" size:16];
FileNameLabel.font = [UIFont boldSystemFontOfSize:16];
FileNameLabel.textColor = [UIColor blackColor];
[cell.contentView addSubview: FileNameLabel];
[FileNameLabel release];
UILabel *UploadTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, 150, 25)];
UploadTimeLabel.tag = 2000;
UploadTimeLabel.backgroundColor = [UIColor clearColor];
UploadTimeLabel.font = [UIFont fontWithName:#"Helvetica" size:12];
UploadTimeLabel.textColor = [UIColor grayColor];
[cell.contentView addSubview: UploadTimeLabel];
[UploadTimeLabel release];
UILabel *pricelabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 0, 80, 30)];
pricelabel.backgroundColor = [UIColor clearColor];
pricelabel.font = [UIFont fontWithName:#"Helvetica" size:16];
pricelabel.font = [UIFont boldSystemFontOfSize:16];
pricelabel.textColor = [UIColor darkGrayColor];
pricelabel.tag = 3000;
//pricelabel.hidden = YES;
pricelabel.textAlignment = NSTextAlignmentRight;
[cell.contentView addSubview: pricelabel];
[pricelabel release];
market = [[UIButton alloc] init];;
[market setFrame:CGRectMake(200, 6, 30, 30)];
market.tag = 4000;
[market addTarget:self action:#selector(marketPressedAction:) forControlEvents:UIControlEventTouchDown];
[cell.contentView addSubview:market];
}
if( [temp count] > 0)
{
UILabel *fileNameLbl = (UILabel*)[cell.contentView viewWithTag:1000];
fileNameLbl.text =[temp objectAtIndex:indexPath.row];
UILabel *uploadlbl = (UILabel*)[cell.contentView viewWithTag:2000];
uploadlbl.text =[UploadTimeAllArr objectAtIndex:indexPath.row];
}
UIButton *marketButton = (UIButton*)[cell.contentView viewWithTag:4000];
[marketButton setTag:indexPath.row];
if([sellingArray count]>0)
{
NSLog(#"sellingArray %#",sellingArray);
if([[sellingArray objectAtIndex:indexPath.row] isEqualToString:#"0"]) // nothing
{
[marketButton setSelected:NO];
[marketButton setImage:[UIImage imageNamed:#"Marketplace.png"] forState:UIControlStateNormal];
marketButton.enabled = YES;
}
else if([[sellingArray objectAtIndex:indexPath.row] isEqualToString:#"2"]) // marketplace
{
[marketButton setSelected:YES];
[marketButton setImage:[UIImage imageNamed:#"MarketplaceSelect.png"] forState:UIControlStateNormal];
marketButton.enabled = YES;
}
}
return cell;
}
Your main problem here is that you are recreating new views in your cell every time this method is called. You want to create all reusable elements inside the if(cell == nil) otherwise it will make duplicates. Anything that is dynamic must be created outside of this. I took your code and modified it. This should work better.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// Everything that does not change should go in here!
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
UILabel *pricelabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 0, 80, 30)];
pricelabel.backgroundColor = [UIColor clearColor];
pricelabel.font = [UIFont fontWithName:#"Helvetica" size:16];
pricelabel.font = [UIFont boldSystemFontOfSize:16];
pricelabel.textColor = [UIColor darkGrayColor];
pricelabel.tag = 3000;
//pricelabel.hidden = YES;
pricelabel.textAlignment = NSTextAlignmentRight;
[cell addSubview:pricelabel];
UIButton *market = [UIButton buttonWithType:UIButtonTypeCustom];
[market setFrame:CGRectMake(200, 6, 30, 30)];
[market addTarget:self action:#selector(marketPressedAction:) forControlEvents:UIControlEventTouchDown];
[cell addSubview:market];
}
// find market button, since we could be reusing a cell we cannot rely on a tag
// value to find it. (This would only work with one button though).
UIButton *market;
for (UIView *subview in cell.subviews) {
if ([subview isKindOfClass:[UIButton class]]) {
market = (UIButton *)subview;
break;
}
}
// set all defaults in case of reuse
[market setImage:[UIImage imageNamed:#"DefaultImage.png"] forState:UIControlStateNormal];
market.selected = YES;
market.enabled = NO;
market.clearsContextBeforeDrawing = NO;
if([sellingArray count] > 0) {
NSLog(#"sellingArray %#",sellingArray);
if([[sellingArray objectAtIndex:indexPath.row] isEqualToString:#"0"]) {
// not sure if this is supposed to be YES or NO
market.clearsContextBeforeDrawing = YES;
[market setSelected:NO];
[market setImage:[UIImage imageNamed:#"Marketplace.png"] forState:UIControlStateNormal];
market.enabled = YES;
}
}
[market setTag:indexPath.row];
return cell;
}
Since it appears you are not using ARC, make sure you look over this code for any needed reference counting.
dequeReusablecellWithIdentifier: method get return the cell instance already created available,If the reference points still to nil ,we need a valid cell and create one cell to return from that cellForRowatIndexpath: method.That is what being checked in the (cell ==nil).When you create a new cell it is creation and hence all settings custom and all has to be done here.
Second Edit:
This was copied from an answer above:
inside the -cellForRowAtIndexPath: method:
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellSubtitle];
UIButton *market = [UIButton buttonWithType:UIButtonTypeCustom];
[market setFrame:CGRectMake(200, 6, 30, 30)];
[market addTarget:self action:#selector(marketPressedAction:) forControlEvents:UIControlEventTouchDown];
[cell.contentView addSubview:market];
//Add all your UILabel INITIATION stuff here as well
}
UIButton *marketButton;
for (UIView *subview in cell.subviews) {
if ([subview isKindOfClass:[UIButton class]]) {
marketButton = (UIButton *)subview;
break;
}
}
marketButton.tag = [indexPath row];
UILabel *priceLabel = [cell.contentView viewWithTag:3000];
UILabel *uploadTimeLabel = [cell.contentView viewWithTag:2000];
//Set up your labels and button now
return cell;
}
EDIT: Leaving my original answer below for posterity but I see that you are setting the table index row as the MarketButton's tag. If you're using that to figure out which dataSource object to query, this is bad practice. You should be making a custom cell which can hold a reference to the object in your data source, so you don't have to ask the button for its tag, and then ask the data source array for the object at index:tag.
The reason this is bad is because somewhere, the state of your array could change, but the table cell is still displayed and still holds a tag pointing at the wrong index. If you just have the cell keep track of the object in question, no matter what happens to the array structure you're guaranteed to be modifying the object you need to.
The only thing I would change about Firo's answer is to just add a "tag" property to each view in the cell, so you don't have to iterate each time you want to find it.
Also took out the [[UIButton alloc]init] line because it's superfluous and might be considered a dangling pointer.
if (cell == nil) {
// Everything that does not change should go in here!
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
UIButton *market = [UIButton buttonWithType:UIButtonTypeCustom];
[market setFrame:CGRectMake(200, 6, 30, 30)];
[market addTarget:self action:#selector(marketPressedAction:) forControlEvents:UIControlEventTouchDown];
market.tag = 9999;
[cell.contentView addSubview:market];
}
//don't have to do UIView iteration here
UIButton *marketButton = [cell.contentView viewWithTag:9999];
Related
I am facing an issue in custom cell, while scrolling up and down the values in the cell changing. I have added 2 buttons in the last section. Please check the below code. Any help, much appreciated. Thanks a ton.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"cell";
DrinkCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[DrinkCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
if (indexPath.section == [tableView numberOfSections] - 1)
{
cell.tileImage.hidden = YES;
cell.pizzaTopins.hidden = YES;
// cell.accessoryType = UITableViewCellAccessoryNone;
if (indexPath.row == 0) {
cell.separatorInset = UIEdgeInsetsMake(0.f, 0.f, 0.f, cell.bounds.size.width);
UILabel *calorieLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, cell.contentView.frame.size.height/2-30/2, self.tableView.frame.size.width, 30)];
calorieLabel.text = #"1000 Calories | 700 grams of fat";
cell.backgroundColor = backgroundColorApp;
[cell addSubview:calorieLabel];
}
else if (indexPath.row == 1) {
cell.backgroundColor = backgroundColorApp;
NSLog(#"cell width : %f",cell.contentView.frame.size.width);
UIView *quantityView = [[UIView alloc]init];
quantityView.frame = CGRectMake(25 ,cell.contentView.frame.size.height/2-50/2, cell.contentView.frame.size.width-55, 50);
quantityView.backgroundColor = [UIColor whiteColor];
quantityView.clipsToBounds = YES;
quantityView.userInteractionEnabled = YES;
quantityView.layer.cornerRadius = 10.0f;
UIButton *decreaseButton = [[UIButton alloc]initWithFrame:CGRectMake(10, quantityView.frame.size.height/2-35/2, 35, 35)];
[decreaseButton setTitle:#"-" forState:UIControlStateNormal];
[quantityView addSubview:decreaseButton];
[decreaseButton addTarget:self action:#selector(decreaseQuantity:) forControlEvents:UIControlEventTouchUpInside];
[decreaseButton setTitleColor:quantityButtonColor forState:UIControlStateNormal];
[decreaseButton setTintColor:[UIColor greenColor]];
decreaseButton.clipsToBounds = YES;
decreaseButton.layer.cornerRadius = 17.5f;
decreaseButton.layer.borderColor = quantityButtonColor.CGColor;
decreaseButton.layer.borderWidth = 1.5f;
int i =0;
quantityLabel = [[UILabel alloc]initWithFrame:CGRectMake(quantityView.frame.size.width/2-30/2, quantityView.frame.size.height/2-30/2, 30, 30)];
quantityLabel.text = [NSString stringWithFormat:#"%d",i];
[quantityLabel setFont:[UIFont boldSystemFontOfSize:18]];
quantityLabel.textColor = quantityButtonColor;
[quantityView addSubview:quantityLabel];
UIButton *increaseButton = [[UIButton alloc]initWithFrame:CGRectMake(quantityView.frame.size.width-45, quantityView.frame.size.height/2-35/2, 35, 35)];
[increaseButton setTitle:#"+" forState:UIControlStateNormal];
[increaseButton addTarget:self action:#selector(increaseQuantity:) forControlEvents:UIControlEventTouchUpInside];
[quantityView addSubview:increaseButton];
increaseButton.clipsToBounds = YES;
[increaseButton setTitleColor:quantityButtonColor forState:UIControlStateNormal];
increaseButton.layer.cornerRadius = 17.5f;
increaseButton.layer.borderColor = quantityButtonColor.CGColor;
increaseButton.layer.borderWidth = 1.5f;
[cell addSubview:quantityView];
[quantityView addSubview:decreaseButton];
[quantityView addSubview:increaseButton];
}
else if (indexPath.row == 2) {
addTocartButton = [[UIButton alloc]initWithFrame:CGRectMake(25, cell.contentView.frame.size.height/2 - 50/2, cell.contentView.frame.size.width-55, 50)];
[addTocartButton setTitle:#"Add to Cart" forState:UIControlStateNormal];
[addTocartButton addTarget:self action:#selector(addToCartOnCreatePizza:) forControlEvents:UIControlEventTouchUpInside];
addTocartButton.backgroundColor = [UIColor colorWithRed:190.0f/255.0f green:19.0f/255.0f blue:31.0f/255.0f alpha:1.0];
// [cell.contentView addSubview:addTocartButton];
[cell.contentView insertSubview:addTocartButton atIndex:0];
addTocartButton.clipsToBounds = YES;
addTocartButton.layer.cornerRadius =10.0f;
}
}
cell.pizzaTopins.textColor = [UIColor colorWithRed:190.0f/255.0f green:19.0f/255.0f blue:31.0f/255.0f alpha:1.0];
cell.pizzaTopins.text = [dataArray objectAtIndex:indexPath.row];
cell.tileImage.image = [UIImage imageNamed:#"profile44.png"];
// cell.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
return cell;
}
dequeueReusableCellWithIdentifier will "reuse" previously created cells so you have to make sure to re-initialize all manually added/modified attributes including any buttons you added programatically.
Screen shots would help us properly diagnose the issue but your code is vulnerable to lingering attributes of reused cells so I would suggest starting with that.
BTW you would probably end up with simpler code if you defined multiple cell prototypes in IB and varied the cellIdentifier based on the indexPath row.
I know this question has many answers already, but not got the solution of my problem.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
NSString *CellIdentifier = #"Cell";//[NSString st ringWithFormat:#"S%1dR%1d",indexPath.section,indexPath.row];
//UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UITextField *textField_Name, *textField_PhoneNumber;
UIButton *button_AddToMyCon;
if(cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell setBackgroundColor:[UIColor clearColor]];
if (indexPath.row < rowcount-2) {
textField_Name = [[UITextField alloc]init];
textField_PhoneNumber = [[UITextField alloc]init];
textField_Name.frame = CGRectMake(10, (cell.frame.size.height-20)/2, 143, 30);
textField_PhoneNumber.frame = CGRectMake(167, (cell.frame.size.height-20)/2, 143, 30);
textField_Name.delegate = self;
textField_PhoneNumber.delegate = self;
textField_Name.borderStyle = UITextBorderStyleRoundedRect;
textField_PhoneNumber.borderStyle = UITextBorderStyleRoundedRect;
textField_Name.attributedPlaceholder = [[NSAttributedString alloc] initWithString:#"Link Name" attributes:#{NSForegroundColorAttributeName: [UIColor lightGrayColor]}];
textField_PhoneNumber.attributedPlaceholder = [[NSAttributedString alloc] initWithString:#"Web Link / URL" attributes:#{NSForegroundColorAttributeName: [UIColor lightGrayColor]}];
textField_Name.layer.cornerRadius = 5.0;
textField_Name.clipsToBounds = YES;
[textField_Name.layer setBorderColor:[UIColor lightGrayColor].CGColor];
[textField_Name.layer setBorderWidth:0.5];
textField_Name.font = [UIFont fontWithName:#"arial" size:15.0];
textField_PhoneNumber.layer.cornerRadius = 5.0;
textField_PhoneNumber.clipsToBounds = YES;
[textField_PhoneNumber.layer setBorderColor:[UIColor lightGrayColor].CGColor];
[textField_PhoneNumber.layer setBorderWidth:0.5];
textField_PhoneNumber.font = [UIFont fontWithName:#"arial" size:15.0];
textField_Name.textColor = [UIColor colorWithRed:(152.0f/255.0f) green:(152.0f/255.0f) blue:(152.0f/255.0f) alpha:1.0f];
textField_PhoneNumber.textColor = [UIColor colorWithRed:(152.0f/255.0f) green:(152.0f/255.0f) blue:(152.0f/255.0f) alpha:1.0f];
// textField_Name.tag=501+indexPath.row;
textField_Name.tag = ktagName;
NSLog(#"textField_Name.tag %ld",(long)textField_Name.tag);
//textField_PhoneNumber.tag=701+indexPath.row;
textField_PhoneNumber.tag =ktagPhn;
NSLog(#"textField_PhoneNumber.tag %ld",(long)textField_PhoneNumber.tag);
if(intEditSave == 1)
{
[textField_Name setUserInteractionEnabled:NO];
[textField_PhoneNumber setUserInteractionEnabled:NO];
}
else
{
[textField_Name setUserInteractionEnabled:YES];
[textField_PhoneNumber setUserInteractionEnabled:YES];
}
textField_PhoneNumber.keyboardType = UIKeyboardTypeURL;
[cell addSubview:textField_Name];
[cell addSubview:textField_PhoneNumber];
UILabel *linelable=[[UILabel alloc]initWithFrame:CGRectMake(0, cell.contentView.frame.size.height+10, cell.contentView.frame.size.width, 0.5)];
[cell.contentView addSubview:linelable];
[linelable setBackgroundColor:[UIColor colorWithRed:(152.0f/255.0f) green:(152.0f/255.0f) blue:(152.0f/255.0f) alpha:0.2f]];
}
else if (indexPath.row==rowcount-2){
NSLog(#"indexPath.row==rowcount-1");
UIButton* button_AddMore = [[UIButton alloc]init];
[button_AddMore setTitle:ktagAdd_More forState:UIControlStateNormal];
[button_AddMore titleLabel].font = [UIFont fontWithName:#"arial" size:15.0];
[button_AddMore setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[button_AddMore addTarget:self action:#selector(addMoreButton:) forControlEvents:UIControlEventTouchUpInside];
// button_AddMore.tag = ktagbutton_AddMore;
button_AddMore.frame = CGRectMake(90, (cell.frame.size.height-20)/2, 140, 30);
[button_AddMore setBackgroundImage:[UIImage imageNamed:#"addMore_button.png"] forState:UIControlStateNormal];
[cell.contentView addSubview:button_AddMore];
button_AddMore.tag=indexPath.row;
}
else if (indexPath.row==rowcount-1)
{
button_AddToMyCon = [[UIButton alloc]init];
[button_AddToMyCon setTitle:ktagAdd_to_MyCon forState:UIControlStateNormal];
[button_AddToMyCon titleLabel].font = [UIFont fontWithName:#"arial" size:15.0];
[button_AddToMyCon setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[button_AddToMyCon addTarget:self action:#selector(save_Fields:) forControlEvents:UIControlEventTouchUpInside];
button_AddToMyCon.tag = ktagbutton_AddToMyCon;
button_AddToMyCon.frame = CGRectMake(90, (cell.frame.size.height-20)/2, 140, 30);
[button_AddToMyCon setBackgroundColor:[UIColor colorWithRed:(234.0f/255.0f) green:(134.0f/255.0f) blue:(59.0f/255.0f) alpha:1.0]];
button_AddToMyCon.layer.cornerRadius=4;
[cell.contentView addSubview:button_AddToMyCon];
UILabel *linelable=[[UILabel alloc]initWithFrame:CGRectMake(0, cell.contentView.frame.size.height+10, cell.contentView.frame.size.width, 0.5)];
[linelable setBackgroundColor:[UIColor colorWithRed:(152.0f/255.0f) green:(152.0f/255.0f) blue:(152.0f/255.0f) alpha:0.2f]];
}
}
return cell;
}
-(void)addMoreButton:(UIButton *)sender
{
rowcount=rowcount+1;
int section = 0;
long row = rowcount;
NSIndexPath* path = [NSIndexPath indexPathForRow:row-3 inSection:section];
[(UITableView *)[self.view viewWithTag:ktagtableView_detailsEdit] insertRowsAtIndexPaths:[NSArray arrayWithObjects:path, nil] withRowAnimation:UITableViewRowAnimationLeft];
NSIndexPath* top = [NSIndexPath indexPathForRow:rowcount-1 inSection:0];
[(UITableView*)[self.view viewWithTag:ktagtableView_detailsEdit] scrollToRowAtIndexPath:top atScrollPosition:UITableViewScrollPositionBottom animated:YES]; //
//[(UITableView *)[self.view viewWithTag:ktagtableView_detailsEdit]reloadData];
}
Here the scenario is that the tableview has 4 rows default each containing two textfields. And a add more button and one save button. On the click of add more button one row is added each time. Please guis for above.
cell instance doesn't have a initial value. Set it to nil on first line first.
A more proper way:
{
NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// add subviews to cellview
}
// set data to subviews
}
I have tried to show a custom view with an accept button and decline button (as subviews) in a table view cell. I have the following code implemented:
tableView: cellForRowAtIndexPath: method
...
if ([status isEqualToString:#"pending"] || [status isEqualToString:#"declined"]){
cell.accessoryView = [self setAccessoryViewForCell:cell];
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
...
- (UIView *)setAccessoryViewForCell:(UITableViewCell *)cell
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(192, 0, 128, 44)];
UIButton *acceptButton = [[UIButton alloc] initWithFrame:CGRectMake(2, 5, 60, 34)];
UIButton *declineButton = [[UIButton alloc] initWithFrame:CGRectMake(66, 5, 60, 34)];
[acceptButton setTitle:#"A" forState:UIControlStateNormal];
[declineButton setTitle:#"D" forState:UIControlStateNormal];
[acceptButton addTarget:self action:#selector(acceptButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[declineButton addTarget:self action:#selector(declineButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:acceptButton];
[view addSubview:declineButton];
return view;
}
I have tried to debug it, but the methods are called appropriately.
Finally, the problem was not in the cellForRowAtIndexPath: method, but in the setAccessoryViewForCell: method. When creating a view for containing two buttons as subviews I really should not have used literal values for the frames. Instead of setting a view for accessoryView property, I rewrote the whole cellForRowAtIndexPath: method and added a subview to the cell's contentView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"notificationsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}
PFObject *user = [self.objects objectAtIndex:indexPath.row];
NSString *firstName = [user objectForKey:#"firstName"];
NSString *lastName = [user objectForKey:#"lastName"];
cell.textLabel.text = [NSString stringWithFormat:#"%# %#", firstName, lastName];
UIView *view = [UIView new];
view.frame = CGRectMake(230, 2, 80, 40);
view.backgroundColor = [UIColor whiteColor];
UIButton *acceptButton = [UIButton buttonwithType:UIButtonTypeCustom];
UIButton *declineButton = [UIButton buttonWithType:UIButtonTypeCustom];
[acceptButton setTitle:#"" forState:UIControlStateNormal];
[declineButton setTitle:#"" forState:UIControlStateNormal];
[acceptButton setImage:[UIImage imageNamed:#"Ok.png"] forState:UIControlStateNormal];
[declineButton setImage:[UIImage imageNamed:#"Close.png"] forState:UIControlStateNormal];
[acceptButton addTarget:self action:#selector(acceptButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[declineButton addTarget:self action:#selector(declineButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
acceptButton.frame = CGRectMake(CGRectGetMinX(view.bounds), CGRectGetMinY(view.bounds), CGRectGetWidth(view.bounds)/2, CGRectGetHeight(view.bounds));
declineButton.frame = CGRectMake(CGRectGetMidX(view.bounds), CGRectGetMinY(view.bounds), CGRectGetWidth(view.bounds)/2, CGRectGetHeight(view.bounds));
[view addSubview:acceptButton];
[view addSubview:declineButton];
[cell.contentView addSubview:view];
return cell;
}
The main difference was that when setting the frames for each button, I used literal values (not a good practice) and now I used the CGRect functions CGRectGetMinX(CGRect rect), CGRectGetMinY(CGRect rect), CGRectGetWidth(CGRect rect), CGRectGetMidX(CGRect rect) and CGRectGetHeight(CGRect rect) to get more accurate values for setting each button's frame. This was a misunderstanding of how a UIView's frames work, I recommend always to use these functions to get the origin and size of subviews and not to use literal values.
The problem appeared to be you are not returning the UIView from setAccessoryViewForCell method.
return view;
Please return the view from the mentioned method, it might solve your problem.
I have a UITableView that has its delegate and dataSource properties set correctly, however its content isn't showing.
MY Code
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
BOOL notInputNotes;
UIColor *normalBlue = [[UIColor alloc]initWithRed:0.1 green:0.65 blue:1.0 alpha:0.8];
HomeWork *hw = [hwArray objectAtIndex:indexPath.row];
NSString *dateDueAsText = [dateFormat stringFromDate:hw.dateDue];
CGFloat xForDate;
if (dateDueAsText.length < 16 || dateDueAsText.length == 16) {
xForDate = 215;
}
else{
xForDate = 214;
}
hw.indexPath = indexPath;
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
for (UIView *view in cell.subviews) {
[view removeFromSuperview];
}
if (!isEditing) {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[cell setEditing:NO];
}
else{
cell.selectionStyle = UITableViewCellSelectionStyleDefault;
[cell setEditing:YES];
}
UILabel *subject = [[UILabel alloc]initWithFrame:CGRectMake(70, 5, 150, 45)];
if(![hw.subject isEqualToString:#""])
{
subject.text = hw.subject;
notInputNotes = NO;
}
else{
subject.text = hw.notes;
subject.frame = CGRectMake(70, 20, 150, 45);
notInputNotes = YES;
}
[subject setFont:[UIFont systemFontOfSize:20]];
[subject setTextColor:normalBlue];
subject.adjustsFontSizeToFitWidth = YES;
subject.backgroundColor = [UIColor blueColor];//test
[cell addSubview:subject];
if(!notInputNotes){
UILabel *notes = [[UILabel alloc]initWithFrame:CGRectMake(70, 40, 300, 30)];
notes.text = hw.notes;
[notes setFont:[UIFont systemFontOfSize:12]];
notes.adjustsFontSizeToFitWidth = YES;
[notes setTextColor:[UIColor colorWithRed:0.2 green:0.3 blue:1.0 alpha:1.0]];
[cell addSubview:notes];
}
UILabel *importancy = [[UILabel alloc]initWithFrame:CGRectMake(300, 45, 200, 30)];
importancy.text = hw.importancy;
[importancy setFont:[UIFont systemFontOfSize:12]];
[importancy setTextColor:[UIColor redColor]];
importancy.adjustsFontSizeToFitWidth = YES;
[cell addSubview:importancy];
UILabel *dateDue = [[UILabel alloc]initWithFrame:CGRectMake(xForDate, 10, 200, 30)];
dateDue.text = [NSString stringWithFormat:#"%#",dateDueAsText];
[dateDue setFont:[UIFont systemFontOfSize:13]];
dateDue.textColor = normalBlue;
dateDue.adjustsFontSizeToFitWidth = YES;
[cell addSubview:dateDue];
hw.doneButton = [[UIButton alloc]initWithFrame:CGRectMake(20, 25, 40, 40)];
if(!hw.done){
[hw.doneButton setImage:[UIImage imageNamed:#"unchecked.png"] forState:UIControlStateNormal];
}
else{
[hw.doneButton setImage:[UIImage imageNamed:#"checked.png"] forState:UIControlStateNormal];
}
[hw.doneButton addTarget:hw action:#selector(done:) forControlEvents:UIControlEventTouchUpInside];
NSDateComponents *dayComponent = [[NSDateComponents alloc] init];
dayComponent.day = -1;
NSCalendar *theCalendar = [NSCalendar currentCalendar];
NSDate *nowMinus1 = [theCalendar dateByAddingComponents:dayComponent toDate:[NSDate date] options:0];
NSComparisonResult result;
result = [nowMinus1 compare:hw.dateDue];
if(result==NSOrderedDescending && !(hw.done)){
cell.backgroundColor = [UIColor colorWithWhite:0.86 alpha:0.6];
NSLog(#"%# is earlier than %#",dateDueAsText,[dateFormat stringFromDate:nowMinus1]);
[hw.doneButton setImage:[UIImage imageNamed:#"lighter-gray_unckecked.jpg"] forState:UIControlStateNormal];
hw.late = YES;
}
else{
cell.backgroundColor = [UIColor whiteColor];
hw.late = NO;
}
[cell addSubview:hw.doneButton];
return cell;
}
Does somebody know what's wrong there? Thanks in advance.
Note
the cell's background color appears different if you set it, so the cells are there and re correctly made the problem is really with the views
I wouldn't say it is a really good practice to remove all subviews of a UITableViewCell and add your own subviews after. It would be better to subclass UITableViewCell.
That being said, you can try this instead, it will display your content.
for (UIView *view in cell.contentView.subviews) {
[view removeFromSuperview];
}
But your problem definitely comes from you wanting to remove the subviews. If the first problem is cell overlapping try implementing
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return customHeight;
}
I create a tableview has button, this button has been changed image ass different condition. The first load tableview, these buttons set image correct but after condition change, it set image incorrect. Example : If [Selling = 0] , set image "Market.png", else [Selling =2], set image "MarketSelect.png". When value of Selling array changing, i used [_tableview reloadData] but it still not change image. I debug, i see MarketButton is 0x0000. The first load, MarketButton works correct but second load, it is 0x0000. Please give me advice to solve this problem. I tried 2 days but it can not works. thanks much
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (nil == cell) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.button.tag = indexPath.row;
UIButton *market = [UIButton buttonWithType:UIButtonTypeCustom];
[market setFrame:CGRectMake(200, 6, 30, 30)];
market.tag = 4000;
[market addTarget:self action:#selector(marketPressedAction:) forControlEvents:UIControlEventTouchDown];
[cell.contentView addSubview:market];
UILabel *pricelabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 0, 80, 30)];
pricelabel.backgroundColor = [UIColor clearColor];
pricelabel.font = [UIFont fontWithName:#"Helvetica" size:16];
pricelabel.font = [UIFont boldSystemFontOfSize:16];
pricelabel.textColor = [UIColor darkGrayColor];
pricelabel.tag = 3000;
//pricelabel.hidden = YES;
pricelabel.textAlignment = NSTextAlignmentRight;
[cell.contentView addSubview: pricelabel];
[pricelabel release];
}
UIButton *marketButton = (UIButton*)[cell.contentView viewWithTag:4000];
[marketButton setTag:indexPath.row];
if([sellingArray count]>0)
{
NSLog(#"sellingArray %#",sellingArray);
if([[sellingArray objectAtIndex:indexPath.row] isEqualToString:#"0"]) // nothing
{
[marketButton setSelected:NO];
[marketButton setImage:[UIImage imageNamed:#"Marketplace.png"] forState:UIControlStateNormal];
marketButton.enabled = YES;
}
else if([[sellingArray objectAtIndex:indexPath.row] isEqualToString:#"2"]) // marketplace
{
[marketButton setSelected:YES];
[marketButton setImage:[UIImage imageNamed:#"MarketplaceSelect.png"] forState:UIControlStateNormal];
marketButton.enabled = YES;
}
}
}
UILabel *pricelbl = (UILabel*)[cell.contentView viewWithTag:3000];
pricelbl.text =[NSString stringWithFormat:#"$%#",[priceNewArray objectAtIndex:indexPath.row]];
if ([sellingArray count]>0) {
if([[sellingArray objectAtIndex:indexPath.row] isEqualToString:#"2"]){
pricelbl.hidden = NO;
}
else if([[sellingArray objectAtIndex:indexPath.row] isEqualToString:#"0"]){
pricelbl.hidden = YES;
}
}
return cell;
}
marketpressAction :
- (void)marketPressedAction:(id)sender
{
buttonPressed = (UIButton *)sender;
buttontag = buttonPressed.tag;
NSLog(#"Market button click at row %d",buttontag);
}