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



我知道这个问题与其他问题非常相似,但我没有使用这种方法解决问题。我遵循大多数可用的解决方案,但它对我不起作用。我知道当表视图滚动时它会重用单元格,但我不知道维护按钮状态的方法。我会尝试使用以下链接

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

  • IOS:在 uitableviewcell 中维护按钮状态

  • 如何处理自定义表格视图单元格iOS中的收藏夹按钮点击?

做了所有的事情,使用标签,使用接触点,但似乎没有什么能帮助我 me.so。这是我的示例代码

-(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包含来自数据库的唯一ID

和点击事件方法...

- (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];
}
}   

注意:在此代码中,按钮是在故事板中创建的,但我也会尝试不使用故事板

首先,

要更改此行cell.btnsubscribe = (UIButton *)[cell.contentView viewWithTag:303];。请按照以下步骤操作并尝试

  1. 在"自定义subcategoryCell"中,将IBOutlet连接到btnsubscribe
  2. 在情节提要中,您可以将选定的图像和非普通图像都设置为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保留在单元格中的行方法(由于您有自定义单元格类,因此最好将按钮操作移动到单元格类,并通过回调或委托将结果传递给视图控制器。 现在不讨论,而是重新评论(并通过删除来更新clickBtnSubscribe:

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

这些行。假定其他部件工作正常。

在这两种情况下,您都为按钮的正常状态设置了选定和未选择的图像,即UIControlStateNormal。使用所选方法时,不需要再次设置图像。只需将图像设置为正常,并在单元格中正确设置按钮的选定状态为行索引路径或 xib 中的按钮。大功告成。

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

现在,在情节提要中,将图像设置为"正常"和"选定"状态。还要删除索引路径处的行的单元格中的设置图像,就像您在视图中所做的那样。

您可以将按钮的状态维护为-

只初始化一次数组

_arraybtnState = [[NSMutableArray alloc] init];

索引路径处行的单元格将是

最初每个单元格都有以下图像

-(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将像下面这样

消失
-(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];

    }
}  

两个简单的解决方案,实施速度非常快:

  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. 您还可以在数据库或任何持久内容中跟踪这一点,然后您只需加载所选记录的字段包含的任何内容。例如,如果我们谈论的是收藏夹之类的东西,或者在用户做出其他决定之前会存在的东西,这一点更相关。如果只是为了在视图的生命周期内跟踪按钮状态,请忽略答案的这一部分。

如果您需要让它永远保持活动状态(即使应用程序关闭(,那么您很可能需要一个数据库:)

最新更新