【问题标题】:issue with UIButton image in UITableCellViewUITableView 中的 UIButton 图像问题
【发布时间】:2012-06-14 16:41:24
【问题描述】:

我正在制作一个简单的计时器应用程序。我有一个多行的 uitable。在那个表中我放了一个 UIButton。一切正常,到目前为止一切顺利,即我看到按钮出现在每一行中。我接下来需要做的是为 UIButton 设置图像,例如如果计时器正在运行,我想在 UIButton 中显示 stop_button_image,如果计时器已经启动,我想将按钮上的 UIImage 设置为 start_button_image

问题是,如果表格被刷新,那么我会得到一个令人讨厌的回溯,这取决于我放置 UIButton setimage 代码的位置。这是我的代码供参考。

//WORKING CODE: (NOT THAT I WANT)
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        //TESTING - Button
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

        // Try to retrieve from the table view a now-unused cell with the given identifier.
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        // If no cell is available, create a new one using the given identifier.
        if (cell == nil)
        {
            // Use the default cell style.
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

            //TESTING - Button
            [button addTarget:self
                       action:@selector(timerStopStart:)
             forControlEvents:UIControlEventTouchDown];
            [button setTitle:@"Start/Stop" forState:UIControlStateNormal];
            button.frame = CGRectMake(5.0f, 5.0f, 72.0f, 77.0f);
            button.tag = indexPath.row;
            [cell addSubview:button];

    //THIS WORKS IF I PUT THIS HERE
            [button setImage:[UIImage imageNamed:@"button_pause.png"] forState:UIControlStateNormal];

        }
        else 
        {
             //NSLog(@"went here 2");
             button = (UIButton *) [cell viewWithTag:indexPath.row];
        }

//some other logic
    }

//这里的代码中断

        - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
        {
            //TESTING - Button
            UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

            // Try to retrieve from the table view a now-unused cell with the given identifier.
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

            // If no cell is available, create a new one using the given identifier.
            if (cell == nil)
            {
                // Use the default cell style.
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

                //TESTING - Button
                [button addTarget:self
                           action:@selector(timerStopStart:)
                 forControlEvents:UIControlEventTouchDown];
                [button setTitle:@"Start/Stop" forState:UIControlStateNormal];
                button.frame = CGRectMake(5.0f, 5.0f, 72.0f, 77.0f);
                button.tag = indexPath.row;
                [cell addSubview:button];


            }
            else 
            {
                 //NSLog(@"went here 2");
                 button = (UIButton *) [cell viewWithTag:indexPath.row];
            }

//CODE BREAKS HERE
[button setImage:[UIImage imageNamed:@"button_pause.png"] forState:UIControlStateNormal];

    //some other logic
        }

问题在于,当表格刷新时,它会使用代码 button = (UIButton *) [cell viewWithTag:indexPath.row]; 调用该部分。我知道这只是一个参考。

这是我在 iOS 模拟器中遇到的错误。我真的想将该图像代码放在 cell==null 检查之外。任何线索如何做到这一点?

这是我在模拟器中遇到的错误

2012-06-14 12:39:27.246 Timers[5381:10a03] -[UITableViewCell setImage:forState:]: unrecognized selector sent to instance 0x73706e0
2012-06-14 12:39:27.247 Timers[5381:10a03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITableViewCell setImage:forState:]: unrecognized selector sent to instance 0x73706e0'
*** First throw call stack:
(0x150b052 0x16bbd0a 0x150cced 0x1471f00 0x1471ce2 0x136c6 0x7b5e0f 0x7b6589 0x7a1dfd 0x7b0851 0x75b322 

【问题讨论】:

  • 试试 button.tag = indexPath.row + someoffset;第 0 行可能是您的问题。
  • @thelaws - 谢谢。你是对的第 0 行杀了我

标签: iphone ios xcode ios5


【解决方案1】:

问题可能出在 indexPath.row 为零时。在这种情况下,您调用viewWithTag:0,但由于任何 UIView 的标签默认为 0,因此您的许多单元格的子视图都有可能具有值为 0 的标签,而不仅仅是您的 UIButton。

为避免此问题,请尝试在 indexPath.row 中添加一个常量(如 100),然后再将其影响到标签,这样第 0 行的按钮将具有标签 100 而不是 0(第 1 行的按钮将有标签 101,等等...),避免它与任何其他带有标签 0 的子视图混淆。

【讨论】:

  • 非常感谢。那成功了。根据您的建议,我在代码中添加了 100,现在很高兴。呸! button.tag = (indexPath.row)+100; button = (UIButton *) [cell viewWithTag:((indexPath.row)+100)];
【解决方案2】:

是的,这将在第 0 行失败。

button = (UIButton *) [cell viewWithTag:indexPath.row];

indexPath.row 为 0 时返回单元格,因为 cell.tag 为 0。


一般来说,这种方法是行不通的。第一次重用单元格时,该按钮将有错误的标签。例如,如果您在第 18 行中重复使用第 2 行的单元格,那么按钮上的标签将是 2,但您查找的标签是 18。它将返回 nil

为什么不定义一个常量 #define kMyStopStartButtonTag 12345 并始终使用该常量。

if (cell == nil)
{
    …
    button.tag = kMyStopStartButtonTag;
    [cell addSubview:button];
    …
} else {
    button = (UIButton *) [cell viewWithTag:kMyStopStartButtonTag];
}

【讨论】:

  • 我无法定义常量的原因是我在单元格中的每一行旁边都有按钮,我需要知道用户按下了哪个按钮,即用户尝试启动/停止哪个计时器
  • @SamBudda [self.tableView indexPathForCell:(UITableViewCell *)button.superview] in -(IBAction)timerStopStart:(UIButton *)button; 将从按钮获取单元格的 indexPath。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多