我正在制作一个简单的计时器应用程序。我有一个多行的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
}
问题是,当表被刷新时,它会调用带有代码按钮的部分=(UIButton *)[cell viewWithTag:indexPath.row];我知道这只是一个参考。
以下是我在iOS模拟器中遇到的错误。我真的想把那个图像代码放在cell == null check之外。有什么线索可以做到这一点吗?
这是我在模拟器中得到的错误
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
答案 0 :(得分:2)
问题可能是当indexPath.row为零时。在这种情况下,您调用viewWithTag:0
,但由于任何UIView的标记默认为0,因此很可能您的单元格的子视图中有很多标记的值为0,而不仅仅是您的UIButton。
要避免此问题,请尝试在indexPath.row中添加一个常量(如100),然后再将其影响到标记,这样第0行的按钮将具有标记100而不是0(并且第1行的按钮将有标签101,等等......),避免与标签0的任何其他子视图混淆。
答案 1 :(得分:1)
是的,第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];
}