如何从 UITableViewCell 中的自定义 UIButton 中删除触摸延迟

Posted

技术标签:

【中文标题】如何从 UITableViewCell 中的自定义 UIButton 中删除触摸延迟【英文标题】:How to remove touch delay from custom UIButton in UITableViewCell 【发布时间】:2013-11-06 18:38:17 【问题描述】:

我有一个自定义按钮,按下时图像会发生变化。此按钮位于 UITableView 内 UITableViewCell 的 contentView 中。

在图像更改之前按下按钮会有明显的延迟。将按钮从单元格中取出并放入 UIView 中,按下时图像的变化是即时的。

如何消除这种延迟?

值得指出的是,我已经尝试在 UITableView 上设置 delaysContentTouches,但我可以看到它没有任何区别。

这里有一些测试代码可以证明这个问题。创建新项目并将 UITableView 添加到情节提要。

#import "JWViewController.h"

@implementation JWViewController

- (void)viewDidLoad

    [super viewDidLoad];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    self.tableView.delaysContentTouches = NO;


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView  return 1; 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  return 1; 
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath  return return 65.0f; 

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

    UITableViewCell *cell = [[UITableViewCell alloc] init];
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setImage:[UIImage imageNamed:@"apple"] forState:UIControlStateNormal];
    [button setImage:[UIImage imageNamed:@"apple_selected"] forState:UIControlStateHighlighted];
    button.frame = CGRectMake(0, 0, 65, 65);
    [cell.contentView addSubview:button];
    return cell;


@end

我已经搜索过,似乎有很多 other posts 与此相关,但没有一个有效的答案。

This blog post 在这种简单的情况下似乎也不起作用。

【问题讨论】:

它可以在 ios 6 上运行吗?当我写那篇文章时,iOS 7 并不存在。 :o) 我去看看... 为 6 编译了我的测试应用程序,但我仍然得到延迟。 您是否尝试记录didSelectRowAtIndexPathtouchesShouldCancelInContentView 的时间?也许这会给你一个线索,让你知道事情可能会延迟。 @JMWhittaker :我已经在类似问题上发布了an answer @staticVoidMan 谢谢你看看 【参考方案1】:

终于解决了你的问题。

试试这个,它会很好用。 在现有代码中添加步骤:- 1.) 设置内容视图中按钮的标签。 2.) 在该按钮上添加目标。

- (void)viewDidLoad
    
        [super viewDidLoad];
        self.tableView.delegate = self;
        self.tableView.dataSource = self;
        self.tableView.delaysContentTouches = NO;
    

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView  return 1; 
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  return 1; 
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath  return 65.0f; 

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    
        UITableViewCell *cell = [[UITableViewCell alloc] init];
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button setImage:[UIImage imageNamed:@"apple.jpg"] forState:UIControlStateNormal];
        [button setImage:[UIImage imageNamed:@"apple_selected.png"] forState:UIControlStateHighlighted];
        button.frame = CGRectMake(0, 0, 65, 65);
        button.tag = indexPath.row;
        [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventAllTouchEvents];
        [cell.contentView addSubview:button];
        return cell;
    

    - (void)buttonPressed:(UIButton *)sender
    
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:sender.tag inSection:0]];

        for (UIView *currentView in cell.subviews)
        
            if ([NSStringFromClass([currentView class]) isEqualToString:@"UITableViewCellScrollView"])
            
                UIScrollView *svTemp = (UIScrollView *) currentView;
                [svTemp setDelaysContentTouches:NO];
                break;
            
        
    

【讨论】:

这段代码很奇怪而且多余。您的 buttonPressed: 方法将被调用很多次,因为您正在使用 UIControlEventAllTouchEvents 控制事件。最好在tableView:cellForRowAtIndexPath: 中循环浏览您的子视图。我能够以此为起点并将以下内容添加到我的UITableViewCell 子类中(在设置方法中):if ([self.superview respondsToSelector:@selector(setDelaysContentTouches:)]) UIScrollView *svTemp = (UIScrollView *)self.superview; [svTemp setDelaysContentTouches:NO]; 【参考方案2】:

我能够使用此解决方案进行修复:https://***.com/a/29259705/1728552

好像table view里面还有另一个scrollview。

【讨论】:

【参考方案3】:

子类UITableView,只实现这个方法:

- (BOOL)touchesShouldCancelInContentView:(UIView *)view

    return YES;

然后设置tableView.delaysContentTouches = NO;

【讨论】:

【参考方案4】:

您需要将触摸事件直接传递给按钮。

 [yourTableViewObject setDelaysContentTouches:NO];

这会在触摸按钮时禁用表格视图的滚动。您可以通过使用手势识别器或子类化 tableview 来实现

- (BOOL)touchesShouldCancelInContentView:(UIView *)view 
return YES;

【讨论】:

以上是关于如何从 UITableViewCell 中的自定义 UIButton 中删除触摸延迟的主要内容,如果未能解决你的问题,请参考以下文章

如何清除包含在重复使用的自定义 UITableViewCell 中的 WKWebview?

如何使用 Interface Builder 中的自定义 UITableViewCell?

Swift - 如何从单元格内单击 UIImageView 上的自定义 UITableViewCell 获取行数据

如何在 Storyboard 中的自定义 UITableViewCell 中配置 UITableView?

如何将子视图添加到情节提要中的自定义 UITableViewCell

如何在ios中的自定义UITableViewCell中添加轮播视图