简体   繁体   中英

UITableView : Cell update after creation ( the right approach)

I have a UITableView with 10 cells.Except the first cell, all are the same.

Around 3 cells are displayed on screen at a time. Each cell has a label which says "Claim". Depending on certain events, I change the "claim" in SOME cells to "claimed".

Problem is when I scroll the cells , the some other cells (whose "claim" I haven't changed to "claimed") also show as "claimed". This seems random and feel is due to cell reuse and poor implementation. Please review the code and help me approach this better.

My requirement is :

  • Display 10 cells out of which all are identical except the first one.
  • All identical cells have a button / label with text "claim"
  • When I press the button , "claim" should change to "Claimed" ONLY for that particular cell in which the button resides.
  • This change should persist event when I scroll.

Custom cell used is :

#import "CustomSaloonCell.h"

@implementation CustomSaloonCell
@synthesize claimButton;
@synthesize delegateListener;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {

        self.claimButton=[UIButton buttonWithType:UIButtonTypeSystem];
        self.claimButton.frame=CGRectMake(30,140,80, 30);
        [self.claimButton setTitle:@"claim" forState:UIControlStateNormal];
        [self.claimButton setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
        self.claimButton.titleLabel.font = [UIFont fontWithName:@"Arial" size:(22)];
        [self.claimButton addTarget:self action:@selector(claimButtonPressed) forControlEvents:UIControlEventTouchUpInside];
        [self.contentView addSubview:self.claimButton];
    }
    return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}



- (void)claimButtonPressed{
    [self.delegateListener didClickedClaimButton:self];
}

@end

The cell creation function :

- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(indexPath.row==0){




            CustomHeaderCell *headerCell = [[CustomHeaderCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"header_cell"];
        headerCell.selectionStyle = UITableViewCellSelectionStyleNone;
            return headerCell;



    }
    static NSString *cellIdentifier = @"HistoryCell";

    // Similar to UITableViewCell, but
    CustomSaloonCell *cell = (CustomSaloonCell *)[theTableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {

        cell = [[CustomSaloonCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];

        cell.selectionStyle = UITableViewCellSelectionStyleNone;


    }


    cell.claimButton.tag = indexPath.row+TAG_OFFSET;

    cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"salon.jpg"]];

    cell.delegateListener = self;

    return cell;
}

The delegate method which modifies the label is :

- (void) claimConfirmedDelegate:(NSInteger)tag{



    CustomSaloonCell *selectedCell=(CustomSaloonCell*)[self.claimTableView cellForRowAtIndexPath: [NSIndexPath indexPathForRow:(tag-TAG_OFFSET)inSection:0]];

    [selectedCell.claimButton setTitle:@"claimed" forState:UIControlStateNormal];
}

Save state of button (also title if your required) in separate instance mutable array. When you pressed button and calling delegate method add that cell indexpath in your buttonStateArray. Now check current indexPath in cellForRowAtIndexPath method: is containing buttonStateArray. If it present then change your button state and title yeah other thing if you want. It will work after scrolling too.

Declare NSMutableArray *buttonStateArray; in .h file of tableview class. Allocate it on initialization or after view loading.

- (void) claimConfirmedDelegate:(NSInteger)tag{

    CustomSaloonCell *selectedCell=(CustomSaloonCell*)[self.claimTableView cellForRowAtIndexPath: [NSIndexPath indexPathForRow:(tag-TAG_OFFSET)inSection:0]];

    [selectedCell.claimButton setTitle:@"claimed" forState:UIControlStateNormal];
    [buttonStateArray addObject:[NSIndexPath indexPathForRow:(tag-TAG_OFFSET)inSection:0]];
}

Now in cellForRowAtIndexPath: method

for (NSIndexPath *selectedIndex in buttonStateArray){
    if([selectedIndex isEqual:indexPath]){
        //Change your state of button.
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM