UITableViewCell中的按钮在iOS 7下无响应

50

我有一个表格视图,每个单元格都包含一个按钮。在所有iOS版本中都可以很好地工作,但在7版本中出现问题。我不知道是怎么回事。该单元格是在一个xib文件中构建的。

能否有人给我一些建议?提前致谢。


11
刚刚遇到了同样的问题。解决方法是确保按钮已添加到内容视图中(即,[self.contentView addSubview:button]),这似乎在iOS6和iOS7之间有所改变。顺便说一下,我认为问题描述得很清楚。我能想到要添加的所有通用UITableView代码。 - mblackwell8
11
厌倦了男人们不试图理解事情就把它搁置一旁。我也有同样的问题,一旦你经历过就很清楚!这并不需要编写代码,实际上是iOS7中的重大变化。 - Stanislav Dvoychenko
大家好,我遇到了同样的问题。我在单元格中使用自定义nib,在iOS7中它们突然都不可交互了。有什么线索吗? - mkto
@Xavier - 你能放到 GitHub 上吗? - DogCoffee
也许你需要创建自定义单元格类并将所有内容添加到内容视图中,而不是使用XIB。这对我很有效... 不需要XIB,只需使用[self.ContentView addSubView:yourbutton]就可以了。 - Dipen Chudasama
我有完全相同的按钮。这两个答案对我没有帮助。这些按钮是self.ContentView的子视图的子视图。 - user4951
24个回答

70

对我有效的方法是:

contentView.userInteractionEnabled = NO;

在从nib文件加载自定义单元格后调用。看起来这个内容视图是在创建nib文件中定义的视图之后创建并设置为顶级子视图。


1
从技术上讲,按钮是内容视图的子视图。将其设置为0将禁用按钮。我错过了什么? - user4951
我也不明白为什么这个解决方案可行(yonix的解决方案对我也没有用)。逻辑上讲,cell的contentView应该像viewController的视图一样。 - Aviel Gross
16
如果您在Xcode 5之前创建了自定义的UITableViewCell,则此方法适用,因为contentView是iOS 7的新内容。如果您的单元格是“旧样式”,则contentView将会遮挡它,这就是为什么在这些情况下它起作用的原因。对于那些已经将按钮作为contentView的子视图的人来说,这种方法无效,需要继续寻找解决方案的过程。 - Bek
非常感谢您!您真的救了我的命。今天我必须冻结我的代码 :) - Srikanth

32

我从nib中加载单元格后,调用[cell bringSubviewToFront:button]解决了这个问题。


4
这个对我不起作用。而且按钮已经在“最前面”了。 - user4951
@JimThio 我刚在这里找到了解决方案:https://devforums.apple.com/message/877894#877894,不确定为什么它有效。我猜测在从nib加载单元格时,iOS7存在一个混乱视图顺序的错误。 - yonix
4
这个方法有效的原因是iOS 7引入了一个中间的 contentView 子视图,用于响应单元格触摸事件。如果这个视图位于你的按钮之上,它将会接收触摸事件而不是按钮。bringSubviewToFront 确保你的按钮在视图堆栈的顶部。 - devios1
1
很棒的回答,Yonix。我尝试了所有的解决方案,但都没有成功。感谢你提供这个简单明了的答案。 - SURESH SANKE

30

我之前也遇到过这个问题,花了很多时间在stackoverflow和互联网上研究不同的答案。解决方法取决于问题的来源。对于大多数情况,您需要对应该接受用户操作(轻点/点击等)的元素执行以下操作:
myButton.userInteractionEnabled = YES;

特别是对于UILabel / UIImageView,默认情况下,userInteractionEnabled标志为 NO

如果您从xib加载视图,您需要确保来自自定义单元格视图、内容视图和要启用用户操作的元素的所有复选框都已选中:
enter image description here

在上面的示例中,DeviceViewCellContent ViewButton元素都选中了"User Interaction Enabled" 复选框。
如果自定义单元格作为UITableViewCell的子类实现,并且自定义单元格视图是动态从另一个xib文件加载的,则您还必须执行另一件事情,这对大多数人来说可能很困惑,但我稍后会解释为什么:
在自定义单元格的初始化方法中,您需要执行以下操作:
self.contentView.userInteractionEnabled = NO

其中self是您创建的UITableViewCell子类。再次强调,如果自定义单元格作为UITableViewCell的子类实现,并且自定义单元格视图是动态从另一个xib文件加载的,则需要执行上述操作。这里是解释:

self.contentView不是您在Interface Builder中看到的那个内容视图(Content View),它是由系统创建的默认内容视图(default content view),位于自定义单元格视图内的所有其他视图/元素之上,遮挡了视图层次结构中的其余部分。因此,在自定义单元格视图中的UI元素可以接收用户交互事件之前,您需要禁用它的用户交互。希望这有所帮助。如果您有更好的解释,我很乐意听取 :-)。再次强调,这是我的观察结果,可能存在其他原因。欢迎讨论!


非常感谢你,us_davis,你解决了我的问题!禁用单元格的contentView的用户交互以获得单元格交互非常奇怪。我真的不明白为什么cell.contentView会盖住其他视图... - Martin
我猜测Xcode和界面构建器之间存在断开连接的问题。在加载自定义的UITableViewCell之前,某种默认的内容视图被创建出来了,我怀疑Xcode需要这样做以避免出现没有内容视图来容纳自定义单元格视图的问题。如果你确实有一个内容视图,它仍然会在你自己的视图上使用其默认的内容视图。我花了相当长的时间才找到这个问题所在。 - us_david
关于self.contentView的观察非常明智。那是根本原因。 - Tchelow
我花了一段时间才发现这一点。很高兴这能帮助遇到类似问题的其他人。 - us_david
谢谢!这正是我的问题,在3D调试视图层次结构中,tableviewcell的内容视图确实在其他所有内容的前面。 - Doug Voss

6
问题在于您的nib文件不包含必须的contentView,这是iOS 8 SDK所要求的(根据我的经验编写,没有可靠的来源,抱歉)。在storyboard中添加UITableViewController时,UITableViewCell会自动添加到它的UITableView中。如果查看这个UITableView,您会看到其中包含一个contentView。
因此,当您子类化UITableViewCell并使用.xib创建它时,您需要将UITableViewCell“点击并拖动”到xib中,而不是默认的UIView。然后别忘了将File Owner类和UITableViewCell类设置为您的子类。

5
这个问题的解决方案是:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {    
cell.bringSubviewToFront(cell.YOUR_UIView)    
}

这对我很有效。


4

显然,有很多问题可能会出现,而某些修复方法只适用于特定的iOS版本,而其他版本则不可行。

我的问题是,我有一个UIButton,它不是cell.contentView的直接子视图(即它是子视图的子视图)。我必须直接将我的按钮添加到cell.contentView中,以使其可点击。(适用于iOS v8+)


4

我遇到了同样的问题。原来是我在IB中创建了一个UIView对象,然后将其类设置为UITableViewCell的子类。

由于我最初在IB中创建的对象是UIView,因此UITableViewCell的contentView直到运行时才被添加,这恰好位于我的UIButtons之上,使它们无法被选中。


3

我一直遇到同样的问题。原因是

self.contentView.Frame.size.height

始终是44。

有一个建议是,在重写方法(void)layoutSubviews时,您可以将self.contentView.Frame设置为self.frame,问题就会得到解决。


这个答案应该出现在更多的帖子中 ;) - Daniel Krzyczkowski

3

我的手机外观

在我的情况下,我希望用户与之交互的所有内容都在ContentView之外。此外,当选中单元格时,我不希望该单元格被突出显示。

所有标签(名称、类别等)都紧接在“内容视图”下方。WebsiteButton不在“内容视图”下,但它在“本地目录表格单元格”下。

在我的tableViewController方法tableView:cellForRowAtIndexPath:中,我有以下代码: cell.contentView.userInteractionEnabled = NO;

这就是全部内容,用户能够与按钮进行交互。 我没有使用[cell bringSubviewToFront:cell.websiteButton];


2
我在这里没有看到的最明显的错误是,您必须为UIButton选择一个selectedBackgroundImage才能在选中时使其外观不同。 这些不像UITableViewCells那样。
myButton.setBackgroundImage(UIImage(named: "ButtonBackgroundSelected.png"), forState: .Highlighted)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接