scrollView 上的子视图touchMove移动失效问题

在有些开发场景下,我们在scrollView上放置了视图,我们想未按住子视图时拖动scrollView,按住子视图时拖动子视图, 但是实际会发现按住视图 ,无法拖动视图,拖动的还是scrollView。

原因是:

手势识别器比UIResponder具有更高的事件响应优先级。
Window在将事件传递给hit-tested view之前,会先将事件传递给相关的手势识别器并由手势识别器优先识别,而scrollView上系统就添加了手势。若手势识别器成功识别了事件,就会取消hit-tested view对事件的响应;若手势识别器没能识别事件,hit-tested view才完全接手事件的响应权。

解决办法: 设置delaysContentTouches = NO. 继承 scrollView 重写下面方法

called before scrolling begins if touches have already been delivered to a subview of the scroll view. if it returns NO the touches will continue to be delivered to the subview and scrolling will not occur
not called if canCancelContentTouches is NO. default returns YES if view isn't a UIControl
this has no effect on presses

- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
    if ([view isKindOfClass:NSClassFromString(@"TestView")]) {  //判断是否是需要拖动的子视图,
        return NO;
    }
    return [super touchesShouldCancelInContentView:view];
}

scrollView.delaysContentTouches = NO;

为什么这样做?

touchesShouldCancelInContentView解读:是否取消给定视图上的touches事件传递。
  • 该方法会在scrollView滚动前调用,前提是touches事件已经传递到子视图上面, 如果返回NO,那么事件就会继续传递到子视图上面,scrollView就不会响应滚动了。
  • canCancelContentTouches=YES时该方法才会调用。canCancelContentTouches:default is YES. if NO, then once we start tracking, we don't try to drag if the touch moves. canCancelContentTouches设置为NO时,表示拖动视图时,不再去drag scrollView。看解释,感觉我们这个需求直接设置这个参数为NO即可,经过我的测试,确实是可以的,但是需要拖动视图时,需要按住一段时间后,才能拖动视图,否则还是会拖动scrollView,这个涉及到手势的识别过程,长按过程中scrollView的手势识别完成后,才会将事件交由hit-tested view。所以设置这个参数为NO是不够达到所需效果的。
  • default returns YES if view isn't a UIControl:在子视图不是UIControl是默认返回YES, 意思子视图是UIControl的话,事件会传递到UIControl上,另一个方面说明UIControl事件优先级更高。
scrollView.delaysContentTouches 解读:这个字段描述的是子控件响应触摸事件是否立即响应触摸事件,默认为YES。
  • 该设置应该是一种优化,因为系统识别手势需要一定的时间判断, 该值默认YES,给手势识别预留了0.15s的时间,在这个时间内,hit-tested view对事件的响应就被延迟,如果直接scrollView手势直接识别了,那么subView的touchBegin都不会执行了。
  • 如果默认为YES的话,会发现按住就马上开始移动手指时还是scrollView在滚动。
    这是因为subView的touchBegin都没执行,也就是说touches事件没有传递到子视图上面touchesShouldCancelInContentView由于条件未达到不会触发。 反而要按住一段时间(0.15s),scrollView的拖动手势没能识别事件后,touches事件传递到subView上,subView的touchesBegin被触发, 再发生移动时触发touchesShouldCancelInContentView调用, 最终subView的touchesMove触发, subView才能拖动。
  • 所以设置为YES,让按下时touches事件就直接传递到subView上,移动时直接触发重写的touchesShouldCancelInContentView。

最后

开发中,响应链、手势、target-action这一系列响应触摸事件,往往混合在一起,出现的问题让人头大,如果不是对iOS触发事件十分深入了解,很难很好的处理到问题,以及处理完了也不知道具体为什么,这里推荐这表文章iOS触摸事件全家桶,这篇文章很深入浅出的讲解了iOS触摸事件的一系列机制。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,817评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,329评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,354评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,498评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,600评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,829评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,979评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,722评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,189评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,519评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,654评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,940评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,762评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,993评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,382评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,543评论 2 349

推荐阅读更多精彩内容