【问题标题】:Apple ipad iphone UITableViewCell with UIButton: change of Button image on Button Click?带有UIButton的Apple ipad iphone UITableViewCell:按钮单击时按钮图像的变化?
【发布时间】:2012-02-14 19:05:51
【问题描述】:

我目前正在开发一个包含 UITableView 的应用程序。 UITableView 包含自定义单元格。在单元格内,我提供了一个 UIbutton,它将用于多行选择。在 tableView 目前我有 30 行并且工作正常但是,当我单击第一行中的按钮时,第 6、11、16、21、26 行中的按钮也会被单击,如果单击之后的第二行下一行被点击(即第 7 行、第 12 行等等...)。

代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil)
        {
            //
            // Create the cell.
            //
            cell =
                [[[UITableViewCell alloc]
                    initWithFrame:CGRectZero
                  reuseIdentifier:CellIdentifier]
                    autorelease];

        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        indicatorImage = [UIImage imageNamed:@"NotSelected.png"];
        indicatorHighImage = [UIImage imageNamed:@"IsSelected.png"];
        selectbtn = [UIButton buttonWithType:UIButtonTypeCustom];
        selectbtn.frame = CGRectMake(30,122,20,20);
        [selectbtn setImage:indicatorImage forState:UIControlStateNormal];
        selectbtn.tag = rowCount++;
        [cell addSubview:selectbtn];
        [selectbtn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
     }
     return cell;
}

-(IBAction)buttonClicked:(UIButton *)button
{
        if([button isSelected])
        {
            [button setImage:indicatorImage forState:UIControlStateNormal];
            [button setSelected:NO];
        }
        else
        {


        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Custom Button Pressed" 
                                                            message:[NSString stringWithFormat: @"You pressed the custom button on cell #%i", button.tag]//pathToCell.row + 1]  
                                                           delegate:self cancelButtonTitle:@"Great" 
                                                  otherButtonTitles:nil];
        [alertView show];
        [alertView release];
        [button setImage:indicatorHighImage forState:UIControlStateNormal];
        [button setSelected:YES];
    }
return;
}

【问题讨论】:

  • 您在表格视图单元格中以文本形式显示的数据类型
  • 我在单元格内显示了一个按钮和一些文本标签。目前我已经对数据进行了硬编码...
  • 我认为您正在使用数组在标签上显示文本。如果是数组,那么数组中包含的是 NSString 还是 NSDictionaries?
  • 我没有使用数组。我在硬编码的所有行中显示相同的文本
  • 然后你只需要在你被选中的按钮上选择或取消选择图像。够了吗

标签: iphone objective-c ios ipad xcode4.2


【解决方案1】:

好的,首先,您错误地设置了按钮图像。要设置选中和未选中的按钮状态,您不必在每次按下按钮时更改图像,只需在创建按钮时执行此操作:

[button setImage:indicatorImage forState:UIControlStateNormal];
[button setImage:indicatorHighImage forState:UIControlStateSelected];

注意 forState 参数 - 这可以让您指定图像将显示的状态,这样当您设置其 selected 属性时,按钮将自动显示另一个图像。在 buttonClicked 方法中,你现在可以说:

button.selected = !button.selected; // toggle selection state

现在的第二个问题是,选择一个按钮会选择其他按钮是由于表格单元格在表格中的回收方式。如果您在一个单元格上设置某些属性(例如选择一个按钮),该单元格将在表格中多次重复使用,并且将保持该状态。一个有 100 行的表格不包含 100 个单元格,它可能有 10 个单元格,当您滚动它时,它只会一遍又一遍地重复使用相同的 10 个单元格。

因此,您不能在表格单元格中存储状态信息。您需要使用模型对象数组来支持您的表格,并且每次调用 cellForRowAtIndexPath 方法时,您都需要使用等效索引从数组中的对象重置单元格属性。

此外,您在 cellForRowAtIndexPath 方法的 if (cell == nil) { ... } 子句中所做的一些事情需要移到 if 语句之外,否则它们只会在第一次创建单元格时设置,不会被设置再次使用时重新设置。

所以你的 cellForRowAtIndexPath 方法应该是这样的:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        if (cell == nil)
        {
            cell =
                [[[UITableViewCell alloc]
                    initWithFrame:CGRectZero
                  reuseIdentifier:CellIdentifier]
                    autorelease];

        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        selectbtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [selectbtn setImage:[UIImage imageNamed:@"NotSelected.png"] forState:UIControlStateNormal];
        [selectbtn setImage:[UIImage imageNamed:@"IsSelected.png"] forState:UIControlStateSelected];
        selectbtn.frame = CGRectMake(30,122,20,20);
        [cell addSubview:selectbtn];
        [selectbtn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
     }

     //get a model object from the array
     MyModelObject *object = [myBackingArray objectAtIndex:indexPath.row];

     //get the button and set its properties
     UIButton *button = [cell.subviews lastObject]; 
     button.tag = rowCountindexPath.row;
     button.selected = object.mySelectedStateProperty;

     return cell;
}

请注意,MyModelObject、myBackingArray 和 object.mySelectedStateProperty 是新类的占位符,您将创建一个新类作为单元格数据的模型,以及存储在视图控制器中的这些对象的数组,作为存储单元格状态的永久位置.

【讨论】:

  • 嘿尼克..感谢您的回复..这很有帮助...但是现在当我向下滚动并再次出现选择消失...该怎么办????
  • 您需要在 buttonClicked 方法中将选定状态保存在您的模型中。所以在 buttonClicked 中说“[myBackingArray objectAtIndex:button.tag].mySelectedStateProperty = button.selected”。这样您就可以在重新创建单元格时从模型中恢复选择。
猜你喜欢
  • 1970-01-01
  • 2016-08-26
  • 2018-09-11
  • 1970-01-01
  • 1970-01-01
  • 2020-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多