我在这里遇到一个奇怪的问题。我有一个TableView,我将indexPath.row分配给UIButton的标记,因此我可以将该标记作为参数传递给segue,并将对象提供给下一个视图控制器。一切都很有效,直到我在TableView中经过6个单元格,按下按钮时会从数组中传递错误的对象。我决定放入一些NSLog来看看发生了什么,我发现结果非常奇怪。赋值buttonForApplyingTag.tag = indexPath.row;
发生在NSLog之后,是return cell;
之前的最后一个语句。由于indexPath.row的实际值是正确的,因此正确地加载了数组中的对象。它只是导致问题的按钮。这是我的输出:
2012-11-28 19:01:57.596 IndexPath.row: 0
2012-11-28 19:01:57.596 IndexPath.Row from Tag: 0
2012-11-28 19:01:57.597 SearchResults Count: 100
2012-11-28 19:01:57.598 IndexPath.row: 1
2012-11-28 19:01:57.598 IndexPath.Row from Tag: 1
2012-11-28 19:01:57.598 SearchResults Count: 100
2012-11-28 19:01:57.599 IndexPath.row: 2
2012-11-28 19:01:57.600 IndexPath.Row from Tag: 2
2012-11-28 19:01:57.600 SearchResults Count: 100
2012-11-28 19:01:57.601 IndexPath.row: 3
2012-11-28 19:01:57.601 IndexPath.Row from Tag: 3
2012-11-28 19:01:57.602 SearchResults Count: 100
2012-11-28 19:01:57.602 IndexPath.row: 4
2012-11-28 19:01:57.603 IndexPath.Row from Tag: 4
2012-11-28 19:01:57.603 SearchResults Count: 100
2012-11-28 19:01:57.604 IndexPath.row: 5
2012-11-28 19:01:57.605 IndexPath.Row from Tag: 5
2012-11-28 19:01:57.605 SearchResults Count: 100
2012-11-28 19:02:02.004 IndexPath.row: 6
2012-11-28 19:02:02.004 IndexPath.Row from Tag: 6
2012-11-28 19:02:02.005 SearchResults Count: 100
2012-11-28 19:02:03.993 IndexPath.row: 7
2012-11-28 19:02:03.993 IndexPath.Row from Tag: 0
2012-11-28 19:02:03.993 SearchResults Count: 100
2012-11-28 19:02:17.846 IndexPath.row: 8
2012-11-28 19:02:17.846 IndexPath.Row from Tag: 0
2012-11-28 19:02:17.846 SearchResults Count: 100
2012-11-28 19:02:18.482 IndexPath.row: 9
2012-11-28 19:02:18.482 IndexPath.Row from Tag: 0
2012-11-28 19:02:18.482 SearchResults Count: 100
抱歉线路过多,但你明白了。这种趋势一直持续到100,这意味着按钮没有收到正确的标签。甚至更奇怪的是,当使用错误的indexPath.row标记单击按钮时,显然会组成另一个标记,并且我得到一个低值标记。此外,当单元格6部分出现在TableView的底部时,即使单元格已经实际加载,NSLog也没有发布到调试器,因此按钮失败并返回5的标记。所以这种做事方式实际上存在3个问题。
真的,我想问的是为什么会发生这种奇怪的行为,我该如何解决?其次,既然这似乎是一场灾难,有没有更好的方法来传递indexPath.row值,这样我就可以在点击按钮时从我的数组中获取一个对象?
感谢您的帮助
问候,
麦克
P.S。我是一个完全的业余爱好者,所以如果你能用Lehmann的话来解释它,我会很感激。
编辑:这是我按照要求将标签实际分配给按钮的代码。
UIButton *buttonForApplyingTag = (UIButton *)[cell viewWithTag:1004];
NSLog(@"IndexPath.row: %d", indexPath.row);
NSLog(@"IndexPath.Row from Tag: %d", buttonForApplyingTag.tag);
NSLog(@"SearchResults Count: %d", [searchResults count]);
buttonForApplyingTag.tag = indexPath.row;
return cell;
编辑2:这是整个cellForRowAtIndexPath代码:
if (isLoading) {
return [tableView dequeueReusableCellWithIdentifier:LoadingCellIdentifier];
} else if ([searchResults count] == 0) {
return [tableView dequeueReusableCellWithIdentifier:NothingFoundCellIdentifier];
} else {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SearchResultCellIdentifier];
[tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[tableView setSeparatorColor:[UIColor grayColor]];
/* Then we do a load of assignments for labels in the cell, then we reach the tagging code. */
SearchResultCellIdentifier
来自:static NSString *const SearchResultCellIdentifier = @"SearchResultCellProto";
答案 0 :(得分:5)
看起来你想要做的是在单元格中有按钮,然后知道按钮动作发生时按下了哪个单元格的按钮。使用标签是一个合理的想法,但很难实现,因为标签需要在重复使用时更改(并最终在不同的索引路径)。
这是一个更好的方法:使用常量标记(或没有标记)添加按钮,然后在点击操作上执行此操作...
- (IBAction)pressedButtonInMyCell:(id)sender {
UIButton *button = (UIButton *)sender;
// find the cell that contains the button, this might be one or two levels
// up depending on how you created the button (one level in code, two in IB, probably)
UIView *view = button.superview;
while (view && ![view isKindOfClass:[UITableViewCell self]]) view = view.superview;
UITableViewCell *cell = (UITableViewCell *)view;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
NSLog(@"cell is in section %d, row %d", indexPath.section, indexPath.row);
}
答案 1 :(得分:3)
此行从单元格中获取按钮:
UIButton *buttonForApplyingTag = (UIButton *)[cell viewWithTag:1004];
但是,在重复使用的单元格中,标记不是1004.实际上是先前使用过单元格时设置的标记。因此buttonForApplyingTag
可能在重用的单元格上为零,整个系统都会失败。
最好创建一个子类化单元格并将UIButton附加到实例变量。
<强>子类:强>
创建一个新的UITableViewCell子类,我们称之为CustomCellView
。确保在cellForRowAtIndexPath
而不是常规UITableViewCell
中实例化此类。向其添加一个名为theButton
的实例变量。然后创建并为此实例变量分配buttonForApplyingTag
。最好在子类的init
中执行此操作。然后在cellForRowAtIndexPath
中,您不必创建按钮,只需使用cell.theButton
。
但是,更好的方法是将'tag'存储在子类的实例变量整数中。