[英]issue with UIButton image in UITableCellView
I am making a simple timer app. 我正在制作一个简单的计时器应用程序。 I have a uitable with multiple rows.
我有一个多行的uitable。 In that table I have put a UIButton.
在该表中,我放置了一个UIButton。 Everything works and so far so good ie I see the button appear in each row.
一切正常,到目前为止效果很好,即我看到按钮出现在每一行中。 What I needed to do next was to set an image for the UIButton eg if the timer was running I wanted to show stop_button_image in the UIButton and if the timer had started I wanted to set the UIImage on the button to start_button_image
接下来,我需要为UIButton设置一个图像,例如,如果计时器正在运行,我想在UIButton中显示stop_button_image,如果计时器已经启动,我想将按钮上的UIImage设置为start_button_image
The problem is that if the table gets refreshed then I get a nasty traceback depending upon where I had put the UIButton setimage code. 问题是,如果刷新了表,那么我将获得讨厌的回溯,这取决于将UIButton setimage代码放在哪里。 Here is my code for reference.
这是我的代码供参考。
//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
}
//CODE BREAKS HERE //此处有代码中断
- (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
}
The problem is that when the table gets refreshed it calls the section with code button = (UIButton *) [cell viewWithTag:indexPath.row]; 问题是,当刷新表时,它将使用代码button =(UIButton *)[cell viewWithTag:indexPath.row];调用该部分。 which I know is just a reference.
我知道这只是参考。
Here is the error I get in iOS simulator. 这是我在iOS模拟器中遇到的错误。 I really want to put that image code outside the cell==null check.
我真的想将图像代码放在cell == null检查之外。 Any clues how this can be done?
任何线索如何做到这一点?
Here is the error that I get in the simulator 这是我在模拟器中遇到的错误
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
The problem is probably when the indexPath.row is zero. 问题可能出在indexPath.row为零时。 In that case, you call
viewWithTag:0
but as the tag of any UIView is 0 by default, there are chances that a lot of your cell's subview have a tag with the value 0, not only your UIButton. 在这种情况下,您调用
viewWithTag:0
但是由于任何UIView的标签默认情况下均为0,因此,很多单元格子视图都有一个标签值为0的标签,而不仅仅是UIButton。
To avoid this issue, try adding a constant (like 100) to your indexPath.row before affecting it to the tag, so that your button at row 0 will have the tag 100 and not 0 (and button at row 1 will have the tag 101, and so on…), avoiding it to be confused with any other subview with tag 0. 为避免此问题,请在将它影响到标记之前,先向其indexPath.row添加一个常量(例如100),以便第0行的按钮具有标签100而不是0(第1行的按钮具有标签) 101,依此类推...),避免将其与标签为0的任何其他子视图混淆。
Yeah, this will fail for row 0. 是的,这将在第0行失败。
button = (UIButton *) [cell viewWithTag:indexPath.row];
will return cell when indexPath.row is 0, because cell.tag is 0. 当indexPath.row为0时将返回单元格,因为cell.tag为0。
As a general note, this approach will not work. 一般而言,此方法无效。 The first time you reuse a cell the button will have the wrong tag.
第一次重用单元格时,按钮将带有错误的标记。 For example, if you reuse the cell from row 2 in row 18, then the tag on the button will be 2, but the tag you look for is 18. It will return
nil
. 例如,如果您重复使用第18行第2行中的单元格,则按钮上的标签将为2,但您要查找的标签为18。它将返回
nil
。
why not define a constant #define kMyStopStartButtonTag 12345
and use that constant the whole time. 为什么不定义常量
#define kMyStopStartButtonTag 12345
并始终使用该常量。
if (cell == nil)
{
…
button.tag = kMyStopStartButtonTag;
[cell addSubview:button];
…
} else {
button = (UIButton *) [cell viewWithTag:kMyStopStartButtonTag];
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.