iOS-UITableViewCell中的UIButton延迟了“ Touch Down”事件

2020/12/17 05:32 · ios ·  · 0评论

我有一个自定义UITableViewCell,可通过以下方式初始化:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
        self = [nibArray objectAtIndex:0];

        [self setSelectionStyle:UITableViewCellSelectionStyleNone];

        [self.downButton setBackgroundImage:[UIImage imageNamed:@"button"] forState:UIControlStateNormal];
        [self.downButton setBackgroundImage:[UIImage imageNamed:@"buttonSelected"] forState:UIControlStateHighlighted];
    }
    return self;
}

该按钮显示正确,带有适当的背景图像,但是当按下/单击该按钮时,突出显示的图像不会立即出现。相反,您必须先按住一两秒钟,然后再进行更改。另一方面,释放按钮确实可以立即更改回原始背景图像。

为了减轻切换到突出显示图像时的迟缓变化,我将更改放入以下方法中:

- (IBAction)downDown:(id)sender {
    [self.downButton setBackgroundColor:[UIColor redColor]];
}

上面的方法设置为“ Touch Down”(与更常见的“ Touch Up Inside”相对),并且我已删除setBackgroundImage:forState:了突出显示状态的。与上述相同的问题。颜色最终会变为红色,但只有在单击并按住按钮一两秒钟之后,颜色才会变为红色。

我有一种用于按钮的方法,当“ Touch Up Inside”发生时,该方法会被执行,并且该方法执行不会出现问题-不管我是快速点击该按钮,还是在释放前按住它一段时间。

那么,为什么推迟“触地得分”或UIControlStateHighlighted我正在尝试向用户提供即时反馈,以表明该按钮已被按下。

如果需要,我可以提供更多代码,但是这些是与背景外观无关的唯一位。

这是由UIScrollView财产引起的delaysContentTouches

过去仅将属性设置NO为其UITableView本身就足够,但这仅适用于未包含在另一个表中的表的子视图UIScrollView

UITableViewCells 在iOS 7中包含一个内部滚动视图,因此您需要在其中具有按钮的所有单元格的单元格级别上更改此属性的值。

这是您需要做的:

1.inviewDidLoad或类似的地方在您UITableView初始化后,将其放入:

self.tableView.delaysContentTouches = NO;

2.对于iOS 7支持,在您UITableViewCellinitWithStyle:reuseIdentifier:initWithCoder:NIB)的初始化方法中,将其放在最后:

for (UIView *currentView in self.subviews)
{
    if([currentView isKindOfClass:[UIScrollView class]])
    {
        ((UIScrollView *)currentView).delaysContentTouches = NO;
        break;
    }
}

不幸的是,这不是100%永久的解决方案,因为Apple将来可以再次更改单元格内的视图层次结构(也许将滚动视图向下移动另一层,或者可能需要您在其中嵌套另一个循环),但是直到它们浮出水面为止。类或至少对开发人员而言是某种属性,这是我们所拥有的最好的。

斯威夫特

首先,关闭UITableView成功加载后的延迟,例如,内部viewDidLoad()方法:

someTableView.delaysContentTouches = false

然后关闭包含在其中的滚动视图中的延迟UITableView

for case let scrollView as UIScrollView in someTableView.subviews {
    scrollView.delaysContentTouches = false
}

iOS7注意事项:您可能必须禁用中的延迟UITableViewCell(检查迪玛的答案)。您可能还会在这里找到其他提示

我通过子类化UIButton在我的代码中解决了这个问题,

目标C

@interface TBButton : UIButton

@end

@implementation TBButton

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    self.highlighted = true;
    [super touchesBegan:touches withEvent:event];
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    self.highlighted = false;
    [super touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    self.highlighted = false;
    [super touchesCancelled:touches withEvent:event];
}

@end

迅速

class TBButton: UIButton {
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        highlighted = true
        super.touchesBegan(touches, withEvent: event)
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        highlighted = false
        super.touchesEnded(touches, withEvent: event)
    }
    override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
        highlighted = false
        super.touchesCancelled(touches, withEvent: event)
    }
}

迅捷3

class TBButton: UIButton {
    override func touchesBegan(_ touches: Set<UITouch>, with event:     UIEvent?) {
        isHighlighted = true
        super.touchesBegan(touches, with: event)
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event:     UIEvent?) {
        isHighlighted = false
        super.touchesEnded(touches, with: event)
    }

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        isHighlighted = false
        super.touchesCancelled(touches, with: event)
    }
}

Swift 3版本的Alex答案

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    isHighlighted = true
    super.touchesBegan(touches, with: event)
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    isHighlighted = false
    super.touchesEnded(touches, with: event)
}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
    isHighlighted = false
    super.touchesCancelled(touches, with: event)
}

您可以将以下递归解决方案添加到视图控制器中:

+ (void)disableDelayedTouches:(UIView*)view
{
    for(UIView *currentView in view.subviews) {
        if([currentView isKindOfClass:[UIScrollView class]]) {
            ((UIScrollView *)currentView).delaysContentTouches = NO;
        }
        [self disableDelayedTouches:currentView];
    }
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.class disableDelayedTouches:self.view];
}

那么,为什么推迟“触地得分”或UIControlStateHighlighted我正在尝试向用户提供即时反馈,以表明该按钮已被按下。

苹果还没有解释吗?

没有这种延迟:

  1. 如果要滚动视图,并且手指触摸了任何可突出显示的内容(例如,具有默认选择样式的任何表格单元格),则会得到以下闪烁的工件:

    在此处输入图片说明

    的确,他们不知道touchDown,您是否要点击或滚动。

  2. 如果要滚动视图,而手指触摸UIButton/ UITextField则根本不会滚动视图Button / TextField的默认行为比滚动视图的默认行为“强”,它一直在等待touchUpInside事件。

也许这个答案更简单。只需添加动画延迟即可。如下所示:

    [self.publishButton bk_addEventHandler:^(id sender) {
    @strongify(self);
    // reset to normal state with delay
    [UIView animateWithDuration:0.1 animations:^{
        self.publishButton.backgroundColor = [UIColor whiteColor];
    }];
    } forControlEvents:UIControlEventTouchUpInside];

   [self.publishButton bk_addEventHandler:^(id sender) {
    //Set your Image or color
       self.publishButton.backgroundColor = [UIColor redColor];
   } forControlEvents:UIControlEventTouchDown];
本文地址:http://ios.askforanswer.com/ios-uitableviewcellzhongdeuibuttonyanchile-touch-downshijian.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!