滚动时在UITableview单元格中保持自定义按钮的状态

时间:2015-04-08 06:48:55

标签: ios objective-c iphone uitableview

我知道这个问题与其他问题非常相似,但我并没有使用这种方法解决问题。我遵循大部分可用的解决方案,但它对我不起作用.. 我知道当tableview滚动它重用单元格但我不知道维持按钮状态的方法。我将尝试使用以下链接

我做了所有的事情。使用标签,使用触摸点,但似乎没有什么似乎对我有用。所以帮助我...这里是我的示例代码

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

}   
  

注意:在此代码中,按钮是在storyboard中创建的,但我也尝试过没有故事板。

5 个答案:

答案 0 :(得分:1)

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

  1. 在自定义subcategoryCell中将IBOutlet连接到btnsubscribe
  2. 在情节提要中,您可以将选定图像和非普通图像都设置为UIButton,此处为btnsubscribe。如果您发现难以遵循this
  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];
    }
    
  5. 或只是[cell.btnsubscribe setSelected:(![_arraybtnState containsObject:listid] )];

    1. addTarget保留在单元格中用于行方法(因为您有自定义单元格类,最好将按钮操作移动到单元格类并通过回调或委托将结果传递给viewcontroller。现在,但推荐)并通过删除

      更新clickBtnSubscribe:
      [button setImage:[UIImage imageNamed:@"following"] forState:UIControlStateNormal];
      [button setImage:[UIImage imageNamed:@"follow"] forState:UIControlStateNormal];
      
    2. 这些台词。假设其他部分正常工作。

答案 1 :(得分:0)

在两种情况下,您都要为按钮的正常状态设置已选择和未选择的图像,即UIControlStateNormal。 使用选定的方法时,不需要再次使用setImage。只需在cellForRowAtIndexpath或xib中正确设置Image for Normal和selected状态。你完成了。

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

现在,在故事板中为正常和选定状态设置图像。 同样删除索引路径中行的单元格中的图像,就像您在视图中一样。

答案 2 :(得分:0)

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

//只初始化一次数组

_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中。

答案 3 :(得分:0)

我认为您可以将此行放在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];


    }

}  

答案 4 :(得分:0)

两种简单的解决方案,实施起来非常快:

  1. 跟踪数组/词典中的状态
  2. 您可以将状态存储在一系列状态中,我将举例说明。

    (注意:我没有编译就编码了,我可能会误写一些东西,随意编辑我的帖子)

    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. 您还可以在数据库或任何持久性内容中跟踪此信息,然后您只需加载字段包含的所选记录。如果我们正在讨论诸如收藏夹之类的东西,或者在用户另有决定之前将会出现的东西,这就更具相关性。如果只是为了在视图生命周期内跟踪按钮状态,请忽略这部分答案。
    2. 如果你需要永远保持活着(即使应用程序关闭),那么你很可能需要一个数据库:)