滚动时在UITableview单元格中维护自定义button的状态

我知道这个问题是非常相似的其他问题,但我不解决问题,使用该方法。我遵循大部分可用的解决scheme,但它不适用于我..我知道,当tableview滚动它重用单元格,但我不知道保持button状态的方法。 我会尝试以下链接

  • 如何在iOS的uitableview中使用可重用的单元格

  • IOS:维护uitableviewcell中的button状态

  • 如何处理在自定义Tableview单元格iOS中最喜欢的button点击?

我做了所有的东西。使用标签,使用触摸点和所有东西似乎没有为我工作,所以帮助我…这里是我的示例代码

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { cell = (subcategoryCell *)[tableView dequeueReusableCellWithIdentifier:NSStringFromClass([subcategoryCell class]) forIndexPath:indexPath]; /* * Set button for cell to subscribe with it */ cell.btnsubscribe = (UIButton *)[cell.contentView viewWithTag:303]; cell.btnsubscribe.tag = indexPath.row ; [cell.btnsubscribe addTarget:self action:@selector(clickBtnSubscribe:) forControlEvents:UIControlEventTouchUpInside]; if (![_arraybtnState containsObject:listid] ) { [cell.btnsubscribe setImage:[UIImage imageNamed:@"follow"] forState:UIControlStateNormal]; [cell.btnsubscribe setSelected:YES]; } else { [cell.btnsubscribe setImage:[UIImage imageNamed:@"following"] forState:UIControlStateNormal]; [cell.btnsubscribe setSelected:NO]; } return cell; } 

_arrbtnstate包含用户所遵循的ID。
而listid包含的唯一标识也来自数据库

和点击事件的方法…

 - (IBAction)clickBtnSubscribe:(id)sender { UIButton *button = (UIButton*)sender; NSLog(@"selected button tag %li", (long)button.tag); NSNumber *tagnum = [NSNumber numberWithLong:(long)button.tag]; if (button.selected) { [self.arraybtnState addObject:tagnum]; [button setImage:[UIImage imageNamed:@"following"] forState:UIControlStateNormal]; NSLog(@"Subscribe"); [self subscribeButton:button.tag]; [button setSelected:NO]; } else { [self.arraybtnState removeObject:tagnum]; [button setImage:[UIImage imageNamed:@"follow"] forState:UIControlStateNormal]; NSLog(@"unsubscribe"); [self unsubscribeButton:button.tag]; [button setSelected:YES]; } } 

注意:在这段代码中,button是在故事板中创build的,但是我也会尝试没有故事板。

首先这一行cell.btnsubscribe = (UIButton *)[cell.contentView viewWithTag:303]; 是要改变的。 按照下面的步骤,并尝试

  1. 在自定义subcategoryCell连接IBOutletbtnsubscribe
  2. 在故事板中,您可以将select的和非正常的图像设置为UIButton ,在这里是btnsubscribe 。 如果你发现这很困难
  3. cellForRowAtIndexPath:删除下面的行

     [cell.btnsubscribe setImage:[UIImage imageNamed:@"follow"] forState:UIControlStateNormal]; [cell.btnsubscribe setImage:[UIImage imageNamed:@"following"] forState:UIControlStateNormal]; cell.btnsubscribe = (UIButton *)[cell.contentView viewWithTag:303]; 
  4. 更新以下行

     if (![_arraybtnState containsObject:listid] ) { [cell.btnsubscribe setSelected:YES]; } else { [cell.btnsubscribe setSelected:NO]; } 

或简单地[cell.btnsubscribe setSelected:(![_arraybtnState containsObject:listid] )];

  1. 将行方法中的addTarget放在单元格中(因为您有自定义的单元类,最好是将button操作移动到单元类,并通过callback或委托将结果传递给viewcontroller,而不是现在讨论,但是推荐)并更新clickBtnSubscribe:通过删除

     [button setImage:[UIImage imageNamed:@"following"] forState:UIControlStateNormal]; [button setImage:[UIImage imageNamed:@"follow"] forState:UIControlStateNormal]; 

这些线。 假设其他部分正常工作。

在这两种情况下,即在UIControlStateNormal中,您正在设置button正常状态的Selected和Unselected图像。 当你使用选定的方法时,你不需要再次设置图像。 只需在cellForRowAtIndexpath或xib中将Image设置为Normal,并将button的select状态设置为正确。 你完成了。

首先删除clickBtnSubscribe :()方法中的设置图像。

现在在你的故事板设置图像为正常和select状态。 也可以像在视图中已经完成的那样,删除在indexpath中的单元格中设置的图像。

您可以保持button的状态,

/ /只初始化你的数组一次

 _arraybtnState = [[NSMutableArray alloc] init]; 

//在索引path上的行将是

//最初每个单元格都会有跟随图像

 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { cell = (subcategoryCell *)[tableView dequeueReusableCellWithIdentifier:NSStringFromClass([subcategoryCell class]) forIndexPath:indexPath]; [cell.btnsubscribe setTag: indexPath.row]; [cell.btnsubscribe addTarget:self action:@selector(clickBtnSubscribe:) forControlEvents:UIControlEventTouchUpInside]; if (![_arraybtnState containsObject:[NSNumber numberWithInt:indexPath.row]] ) { [cell.btnsubscribe setImage:[UIImage imageNamed:@"follow"] forState:UIControlStateNormal]; [cell.btnsubscribe setSelected:YES]; } else { [cell.btnsubscribe setImage:[UIImage imageNamed:@"following"] forState:UIControlStateNormal]; [cell.btnsubscribe setSelected:NO]; } return cell; } - (IBAction)clickBtnSubscribe:(id)sender { UIButton *button = (UIButton*)sender; NSLog(@"selected button tag %li", (long)button.tag); NSNumber *tagnum = [NSNumber numberWithLong:(long)button.tag]; if (button.selected) { [self.arraybtnState addObject:tagnum]; NSLog(@"Subscribe"); [self subscribeButton:button.tag]; [button setSelected:NO]; } else { [self.arraybtnState removeObject:tagnum]; NSLog(@"unsubscribe"); [self unsubscribeButton:button.tag]; [button setSelected:YES]; } //after doing modification update the respective row as UIButton *button = (UIButton *)sender; // Find Point in Superview CGPoint pointInSuperview = [button.superview convertPoint:button.center toView:self.tableView]; // Infer Index Path NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:pointInSuperview]; //relaod the row NSArray* indexPathModel = [NSArray arrayWithObjects:indexPath, nil]; [self.tableView reloadRowsAtIndexPaths: indexPathModel withRowAnimation:UITableViewRowAnimationNone]; } 

重新加载行将反映模式中对UI所做的更改。

我想你可以把这一行viewDidLoad或加载之后所有已订阅。

  _arraybtnState = [NSMutableArray arrayWithArray:[self.strSubscribe componentsSeparatedByString:@","]]; 

然后cellForRowAtIndexPath将像下面loook

 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { cell = (subcategoryCell *)[tableView dequeueReusableCellWithIdentifier:NSStringFromClass([subcategoryCell class]) forIndexPath:indexPath]; /* * Set button for cell to subscribe with it */ cell.btnsubscribe = (UIButton *)[cell.contentView viewWithTag:303]; cell.btnsubscribe.tag = indexPath.row ; [cell.btnsubscribe addTarget:self action:@selector(clickBtnSubscribe:) forControlEvents:UIControlEventTouchUpInside]; if (![_arraybtnState containsObject:[NSNumber numberWithInt:indexPath.row]] ) { [cell.btnsubscribe setImage:[UIImage imageNamed:@"follow"] forState:UIControlStateNormal]; } else { [cell.btnsubscribe setImage:[UIImage imageNamed:@"following"] forState:UIControlStateNormal]; } return cell; } 

然后按btn点击方法

 - (IBAction)clickBtnSubscribe:(id)sender { UIButton *button = (UIButton*)sender; NSLog(@"selected button tag %li", (long)button.tag); NSNumber *tagnum = [NSNumber numberWithLong:(long)button.tag]; if (![_arraybtnState containsObject:tagnum] ) { [_arraybtnState addObject:tagnum]; [button setImage:[UIImage imageNamed:@"following"] forState:UIControlStateNormal]; NSLog(@"Subscribe"); [self subscribeButton:button.tag]; } else { [self.arraybtnState removeObject:tagnum]; [button setImage:[UIImage imageNamed:@"follow"] forState:UIControlStateNormal]; NSLog(@"unsubscribe"); [self unsubscribeButton:button.tag]; } } 

两个简单的解决scheme,相当快实施:

  1. 跟踪数组/字典中的状态

你可以将你的状态存储在一个状态数组中,我将举例说明。

(注意:我编写这个程序时没有编译,我可能会误解一些东西,随意编辑我的文章)

在你的viewDidLoad

  arrState = [[NSMutableArray alloc]init]; for (yourObject *object in dataArray){ //For every object that you use to load your tableview, this can be strings or anything really [arrState addObject:@NO]; } 

在你的cellForRow

 ... //This will either put YES or NO depending on the element in the state array. [cell.button setSelected:[arrState objectAtIndex:indexPath.row]]; ... 

轰隆,做完了。

  1. 您也可以在数据库或任何持久性logging中logging这一点,然后只需加载您的字段包含的选定logging。 如果我们正在谈论的话,这更具有相关性,例如,像用户喜欢的东西或者其他东西,直到用户决定。 如果只是在视图的生命周期中跟踪button状态,则忽略这部分答案。

如果你需要保持它永远存在(即使应用程序closures),那么你很可能需要一个数据库:)