UITableViewCell 中的 UIButton 从 UITableView 窃取触摸

Posted

技术标签:

【中文标题】UITableViewCell 中的 UIButton 从 UITableView 窃取触摸【英文标题】:UIButton inside UITableViewCell steals touch from UITableView 【发布时间】:2013-04-12 07:38:01 【问题描述】:

我有一个类似于this one 的问题,但提供的答案并没有多大帮助。 我有UITableView 和一些自定义UITableViewCells,这些单元格有一些嵌套的自定义UIViews,最后是一些UIButtons。如上所述,问题是当我触摸按钮时,触摸事件不会填充到UITableView,并且它永远不会滚动。

这是一些代码(这只是最快的重现方式,不是我的实际代码):

@interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>

@property (strong, nonatomic) IBOutlet UITableView * tableView;

@end

@implementation ViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
    
        self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0,
                                                                       self.view.bounds.size.width,
                                                                       self.view.bounds.size.height)
                                                      style:UITableViewStylePlain];
        [self.view addSubview:self.tableView];
        self.tableView.delegate = self;
        self.tableView.dataSource = self;
    
    return self;


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    return 1;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    return 1;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    UITableViewCell * cell = [[UITableViewCell alloc] init];
    UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.backgroundColor = [UIColor redColor];
    button.frame = CGRectMake(0, 0, 50, 44);
    [cell.contentView addSubview:button];
    return cell;


@end

唯一单元格中的红色按钮不会让表格视图反弹滚动。

谁能帮帮我?

附:不要注意我提供的代码的愚蠢性,我知道有关它的所有问题。我只是提供它来显示问题的全部内容。是buttonViewscrollView的冲突。

【问题讨论】:

【参考方案1】:

您可以通过覆盖 UITableView 中的 touchesShouldCancelInContentView: 来更改行为。为此,您需要在 loadView 或您的 xib 文件中用这个子类替换表视图。

@interface AutoCancelTableView: UITableView
@end

@implementation AutoCancelTableView

//
// Overriding touchesShouldCanceInContentView changes the behaviour
// of button selection in a table view to act like cell selection -
// dragging while clicking a button will cancel the click and allow
// the scrolling to occur
//
- (BOOL)touchesShouldCancelInContentView:(UIView *)view 
    return YES;


@end

【讨论】:

谢谢你!现在表格视图页脚中的单元格和按钮的行为完全相同... ;) 可以确认这个有效。请务必将其与tableView.delaysContentTouches = false 结合使用。【参考方案2】:

这是表视图使用的UIScrollView 的标准行为。在您移动手指之前,系统不会知道您要滚动,但到那时您已经“按下”了按钮,因此它假定这就是您想要执行的操作。

您可以在 tableview 的滚动视图上使用几个属性来更改行为,但您可能会发现它们会对单元格和按钮的感觉产生负面影响,因为会增加延迟。

self.tableView.delaysContentTouches = YES;

延迟内容触摸 如果此属性的值为 YES,则滚动视图会延迟处理触摸向下手势,直到它可以确定滚动是否是意图...

self.tableView.canCancelContentTouches = YES

canCancelContentTouches 如果此属性的值为 YES 并且内容中的视图已经开始跟踪触摸它的手指,并且如果用户拖动手指足以启动滚动,则视图接收到 touchesCancelled:withEvent: 消息并且滚动视图处理像滚动一样触摸。

【讨论】:

我仍然无法让它在UITableViews 中为UIControls 工作。另外,由于UITableViewUIScrollView 的子类,您的代码应该是self.tableView.canCancelContentTouches = YES; @johnboiles 你应该设置 elf.tableView.scrollView.delaysContentTouches = NO; 此处答案中显示的组合不起作用。 @johnboiles 是正确的。刚刚对我有用的是:mytable.delaysContentTouches = false 和 mytable.canCancelContentTouches = true。这使我单元格内的按钮正常工作。【参考方案3】:

因为以上所有答案都不适合我。我在按钮上添加了一个 imageView 并使 imageView 用户界面为 YES,然后在 iamgeView 上添加一个点击手势。在点击手势相关的方法中,我将按钮相关的方法放入其中。所以一切都很好.. 可能是黑客。但效果很好..

【讨论】:

【参考方案4】:

以下代码对我有用:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
cell = [tableView dequeueReusableCellWithIdentifier:@"cell_id"];
cell.userInteractionEnabled = YES;
if (cell == nil) 
    cell = [[[CustomCell1 alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell_id"]autorelease];


[cell.button addTarget:self action:@selector(button_action) forControlEvents:UIControlEventTouchUpInside];

-(void)button_actionNSLog(@"Hello!");

这是我的自定义单元格:

#import "CustomCell.h"
@implementation CustomCell
@synthesize button;


- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) 
    button = [[UIButton alloc]init];
    button =[UIColor redColor];
    [self.contentView addSubview: button];
           
return self;

- (void)layoutSubviews 
[super layoutSubviews];
CGRect contentRect = self.contentView.bounds;
CGFloat boundsX = contentRect.origin.x;
CGRect frame;
frame= CGRectMake(boundsX+50 ,+15, 100, 100);
        button = frame;

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
   [super setSelected:selected animated:animated];
// Configure the view for the selected state

【讨论】:

嗯,它不适合我 - 触摸按钮仍然会阻止滚动 tableView。还是谢谢。

以上是关于UITableViewCell 中的 UIButton 从 UITableView 窃取触摸的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 UIButton 标题?

更改 UITableViewCell 中的对象也更改了重用 UITableViewCell 的对象

确定 UITableViewCell 中的 UIButton

UITableViewCell 事件中的 UIButton 不起作用

UITableViewCell 中的 UICollectionView

UITableVIewCell 中的 UIScrollView 不会滚动