UITableViewCell中的UIButton从UITableView窃取了触摸

时间:2013-04-12 07:38:01

标签: ios uitableview uibutton

我遇到类似于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

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

有人可以帮我一点吗?

P.S。不要注意我提供的代码的愚蠢,我知道有关它的所有问题。我只是提供它来展示问题的全部内容。这是buttonViewscrollView的冲突。

4 个答案:

答案 0 :(得分:9)

您可以通过在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

答案 1 :(得分:8)

这是tableviews使用的UIScrollView的标准行为。在您移动手指之前,系统不知道您要滚动,但到那时您已经“按下”了按钮,因此它假设您正在做的事情。

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

self.tableView.delaysContentTouches = YES;
  

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

self.tableView.canCancelContentTouches = YES
  

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

以下代码适用于我:

 - (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_action{NSLog(@"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
}