如何捕获 UIButton 事件:在自定义 UITableViewCell 实现中添加了 UIButton
Posted
技术标签:
【中文标题】如何捕获 UIButton 事件:在自定义 UITableViewCell 实现中添加了 UIButton【英文标题】:How to catch UIButton events: UIButton added inside custom UITableViewCell implementation 【发布时间】:2012-11-21 15:29:32 【问题描述】:有一些discussions关于如何在著名的 UITableCellView 中添加 UIButton
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
方法以及如何处理按钮点击。我已经对它们进行了测试,它们或多或少都可以正常工作。
我的设置略有不同。我想添加 UIButton - 实际上我有几个按钮位于不同的 UIImageViews 上 - 在我的自定义 UITableCellView 类中使用滑动触摸隐藏/显示。为简单起见,我们假设只有一个 UIImageView 添加到单元格的视图堆栈中,并且只有一个 UIButton:
这是我的 UITableViewCell 实现的相关部分:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
// sub menu
self.tableCellSubMenu = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320.0, 88.0)];
[self.tableCellSubMenu setImage:[UIImage imageNamed:@"cell_menu_back"]];
[self addSubview:self.tableCellSubMenu];
UIButton *but = [UIButton buttonWithType:UIButtonTypeCustom];
but.frame = CGRectMake(10.0, 0, 77.0, 88.0);
[but setImage:[UIImage imageNamed:@"cell_menu_icon_plus_up"] forState:UIControlStateNormal];
[but setImage:[UIImage imageNamed:@"cell_menu_icon_plus_down"] forState:UIControlStateSelected];
[but setImage:[UIImage imageNamed:@"cell_menu_icon_plus_down"] forState:UIControlStateHighlighted];
[but addTarget:self action:@selector(tableCellButtonPress:) forControlEvents:UIControlEventTouchUpInside];
[self.tableCellSubMenu addSubview:but];
...
return self;
UIButton 被添加到 UIImageView,而 UIImageView 又被添加到单元格的视图堆栈中。为简单起见,我将按钮的目标配置为“self”。在我的真实设置中,目标是我处理按钮事件的 UITableViewController。我可以保证所有设置都正常工作(例如,通过将 UIImageView 替换为 UIControl,我们稍后会看到)。
不幸的是,在此配置中,按钮上的 touch up inside 事件不会触发。唯一被调用的函数是
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
在控制器中。通常,我将 UIButtons 放在 UIControl 视图上。话虽如此,当我在上面的代码中用 UIControl 替换 UIImageView 时,按钮事件按预期触发,但是,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
不再被调用。我两个都想要。
如何让它工作?
更新 1:
我在自定义 UITableViewCell 实现中实现了以下方法:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
CGPoint location = [((UITouch *)[touches anyObject]) locationInView:self];
if (CGRectContainsPoint(but.frame, location))
[self.touchButtonDelegate tableViewCellButtonTouched:self button:(UIButton*)but indexPath:self.touchButtonIndexPath];
[super touchesBegan:touches withEvent:event];
我仍在使用“UIImageView”对几个按钮进行分组和定位。
self.touchButtonDelegate 是 UITableViewController。 here 提供更完整的解决方案。
【问题讨论】:
尝试将按钮添加到单元格本身,而不是 UIImageView。 当然,这可行,但我需要将按钮添加到某种视图中,以便能够将一组按钮滑出可见区域,例如当用户在表格单元格上滑动以显示子菜单时。 【参考方案1】:UIImageViews 没有启用用户交互。您应该将其添加到单元格本身或另一个 UIView。
【讨论】:
好的,但是要改用什么样的视图呢?正如我所说,我用 UIControl 和 UIView 替换了 UIImageView。这一切都有效,但是,所有 UITableViewDelegate 方法,例如cellForRowAtIndexPath 方法,不要被调用。 对,两者都不会被调用。由于按钮捕获触摸事件的方式,该按钮正在阻止触摸事件到达单元格。如果您希望两者都发生,您可能需要停止使用 UIButtons,而是使用 touchesBegan: 和 touchesEnded: 方法对您的按钮进行一些点击测试以对两者做出反应。并且不要忘记调用这些方法的super
实现以保持表格交互正常工作。以上是关于如何捕获 UIButton 事件:在自定义 UITableViewCell 实现中添加了 UIButton的主要内容,如果未能解决你的问题,请参考以下文章
如何在自定义 UIButton 中实现 .isHighlighted 动画?
在自定义 UITableViewCell 中按下 UIButton 时如何获取 indexPathForSelectedRow