delaysContentTouches和canCancelCo

作者: wMellon | 来源:发表于2017-03-16 22:31 被阅读467次

前言

为什么我会注意到这两个属性呢,因为当初在做一个可编辑的表单时,遇到使用touch方式处理键盘收起但是没效果的情况,具体解决办法请看UITableView键盘隐藏

简述

delaysContentTouches和canCancelContentTouches都是scrollView的一个属性,在讲这两个属性之前,首先要讲下scrollView的一个机制。

从你的手指touch屏幕开始,scrollView开始一个timer,如果:

  1. 150ms内如果你的手指没有任何动作,消息就会传给subView。
  2. 150ms内手指有明显的滑动(一个swipe动作),scrollView就会滚动,消息不会传给subView。
  3. 150ms内手指没有滑动,scrollView将消息传给subView,但是之后手指开始滑动,scrollView传送touchesCancelled消息给subView,然后开始滚动。

delaysContentTouches:默认值为YES。如果设置为NO,则会立即把事件传递给subView。
canCancelContentTouches:默认为YES,如果设置为NO,这消息一旦传递给subView,这scroll事件不会再发生。

实践

在storyboard拉入一个scrollView,然后在scrollView里面拉一个view,这个view是自定义的view,实现如下方法

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"摸到了");
}
-(void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"不摸了");
}

storyboard张这样

E4057C7D-ACCC-41BE-8238-8E045735E6A7.png

情形一:delaysContentTouches和canCancelContentTouches都为YES(即默认情况)

QQ20170316-220029.gif

上图显示
第一次,点击中间的view之后,先停顿一会,之后再开始拖拽(下同)。停顿时scrollView把事件传递给view,view响应了touchesBegan事件。之后开始拖拽,这时view收到了touchesCancelled事件,然后开始滚动了。
第二次,点击中间的view之后,直接开始拖拽(下同)。因为中间没有停顿,所以view没有接收到任何事件。

情形二:delaysContentTouches为NO和canCancelContentTouches为YES

QQ20170316-220810.gif

上图显示
第二次,虽然点击后直接开始拖拽,但是因为scrollView把事件传递给subView是没有延迟的,所以view就立马接收到touchesBegan事件,拖动的那一瞬间,view又接收到touchesCancelled事件。
那第一次,就不用说了。

情形三:delaysContentTouches为YES和canCancelContentTouches为NO

QQ20170316-221420.gif

第一次,停顿时scrollView把事件传递给view,view响应了touchesBegan事件,所以控制台打出了“摸到了”。之后开始滚动,但是view不会接收touchesCancelled事件,而是阻止了scrollView的滚动。
第二次,因为中间没有停顿,所以view压根没接收到touch事件,所以也没法阻止scrollView的滚动。

情形四:delaysContentTouches和canCancelContentTouches都为NO

QQ20170316-221904.gif

第二次,虽然点击后直接开始拖拽,但是因为scrollView把事件传递给subView是没有延迟的,所以view就立马接收到touchesBegan事件。之后开始拖曳,但是view不会接收touchesCancelled事件,而是阻止了scrollView的滚动。
第一次,也不用说了。
至此,这两个属性的用处大家应该都清楚了吧。

切记

千万不要在tableView上试delaysContentTouches属性,那会让你试到怀疑人生的。这个属性在tableView上根本没有效果。这点我也没找到原因,还是在我同事的提醒下,我才意识到这点。


如果本文让你有那么点觉得“I get”的感觉,请点个赞呗!写作很辛苦,路过请点赞!

相关文章

网友评论

  • Pusswzy:tableview也是可以的 看如下代码
    @Implementation ResponseTableView

    - (instancetype) initWithCoder : (NSCoder *) aDecoder

    {
    self = [super initWithCoder:aDecoder];
    if (self) {
    self.delaysContentTouches = NO;
    //因为 UITableViewWrapperView 在iOS7不属于UIScrollView
    //iOS7
    for (id obj in self.subviews) {
    if ([NSStringFromClass([obj class]) isEqualToString:@"UITableViewCellScrollView"]) {
    UIScrollView *scrollView = (UIScrollView *) obj;
    scrollView.delaysContentTouches = NO;
    break;
    }
    }
    //ios 8
    for (id view in self.subviews) {
    if ([NSStringFromClass([view class]) isEqualToString:@"UITableViewWrapperView"]) {
    if ([view isKindOfClass:[UIScrollView class]]) {
    UIScrollView *scrollView = (UIScrollView *) view;
    scrollView.delaysContentTouches = NO;
    }
    break;
    }
    }
    }
    return self;
    }

    - (BOOL) touchesShouldCancelInContentView : (UIView *) view {
    if ([view isKindOfClass:[UIButton class]]) {
    return YES;
    }
    return [super touchesShouldCancelInContentView:view];
    }
    wMellon:棒棒的
  • dtythicc:学习了!

本文标题:delaysContentTouches和canCancelCo

本文链接:https://www.haomeiwen.com/subject/wvksnttx.html