【问题标题】:UIButton Tag not being assigned indexPath.row after 6 cellsUIButton 标记在 6 个单元格后未分配 indexPath.row
【发布时间】:2012-11-28 19:31:32
【问题描述】:

我在这里遇到了一个奇怪的问题。我有一个 TableView 并将 indexPath.row 分配给 UIButton 的标签,这样我就可以将该标签作为参数传递给 segue 并将对象提供给下一个视图控制器。一切正常,直到我通过 TableView 中的 6 个单元格,当按下按钮时,从数组中传递了错误的对象。我决定放入一些 NSLogs 来看看发生了什么,我发现结果很奇怪。赋值buttonForApplyingTag.tag = indexPath.row; 发生在NSLogs 之后,是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 的底部时,即使很明显单元格已实际加载,NSLogs 还没有发布到调试器,因此按钮失败并返回标签 5。所以这种做事方式实际上存在 3 个问题。

真的,我想问的是为什么会发生这种奇怪的行为,我该如何解决?其次,由于这似乎是一场灾难,是否有更好的方法来传递 indexPath.row 值,以便在单击按钮时从数组中获取对象?

感谢您的帮助。
问候,
迈克

附:我是一个完全的业余爱好者,所以如果你能用莱曼的话解释一下,我将不胜感激。

编辑:这是我根据要求将标签实际分配给按钮的代码。

    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";

【问题讨论】:

  • 你能把按钮添加到单元格的代码贴出来吗?
  • 是的。我将进行编辑。
  • 您是否在代码的if (cell == nil) 部分设置标签。如果是,请将其移出。
  • 好的。现在看到你的更新了。在这种情况下,请在设置标签时检查 buttonForApplyingTag 是否为 nil。
  • 也许张贴整个 cellForRowAtIndexPath:有证据表明细胞重用存在问题。

标签: iphone objective-c ios


【解决方案1】:

看起来您想要做的是在单元格中有按钮,然后知道在按钮操作发生时按下了哪个单元格的按钮。使用标签是一个合理的想法,但很难实现,因为标签需要在单元格被重用时进行更改(并以不同的索引路径结束)。

这是一种更好的方法:使用常量标签(或不使用标签)添加按钮,然后在点击操作上执行此操作...

- (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);
}

【讨论】:

  • 很棒的回复。一旦我尝试了其他建议的解决方案,我也会尝试此修复。谢谢你解释得这么清楚。
  • 是的,使用 indexPath 本身肯定更好。当您实际实现此功能时,我建议使用此方法。
  • 好的,那么 Rengers,我将他的标记为正确答案。谢谢你们的帮助。
【解决方案2】:

这一行从单元格中获取按钮:

UIButton *buttonForApplyingTag = (UIButton *)[cell viewWithTag:1004];

但是,在重复使用的单元格中,标签不是 1004。实际上是之前使用单元格时设置的标签。因此,buttonForApplyingTag 在重复使用的单元格上可能为零,整个系统将失败。

最好创建一个子类单元格并将 UIButton 附加到实例变量。

子类化:

创建一个新的 UITableViewCell 子类,我们称之为CustomCellView。确保在 cellForRowAtIndexPath 而不是常规的 UITableViewCell 中实例化此类。向它添加一个名为theButton 的实例变量。然后创建并分配buttonForApplyingTag 给这个实例变量。最好在您的子类的init 中执行此操作。然后在cellForRowAtIndexPath中,就不用创建按钮了,直接用cell.theButton就行了。

但是,将“标签”存储在子类的实例变量整数中会更好。

【讨论】:

  • 对,这绝对是有道理的。我可以看到整个事情会因此而陷入困境。我并没有真正理解“创建子类单元并将 UIButton 附加到实例变量”的意思。我该怎么做呢?
  • 我添加了一个关于如何子类化的粗略大纲。如果这没有意义,我建议您阅读一些 Objective C 基础知识。你可以在网上找到很多教程:)。
  • 太棒了。我现在就这样做并报告。 +2。
  • 对,一件事。当您说将 buttonForApplyingTag 分配给实例变量时。你到底什么意思?您的意思是使用 .tag,因为这肯定会给我们带来与以前相同的问题。对不起,如果我是愚蠢的。
  • 其实不用担心。设法用一个整数实例变量来做到这一点。非常好的修复。谢谢!
猜你喜欢
  • 2012-06-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-20
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
相关资源
最近更新 更多