iOS 全屏侧滑/UIScrollView/UISlider间滑动冲突
效果预览

一、前期准备
有一个支持全屏侧滑返回的视图控制器ViewController,ViewController.view上有一个UIScrollView,UIScrollView上有UISlider。俺直接在之前的示例Demo上演示,地址:iOS 自定义转场动画
二、问题展示
- 现象 1、UIScrollView当前在第一页即contentOffset.x=0时,左滑不能触发全屏侧滑pop返回的手势 ;

- 现象2 、问题1解决后,你会发现拖拽UIScrollView第一页上的UISlider时,向右拖拽时却触发了全屏侧滑pop返回的手势,而UISlider本身的拖拽事件却没有响应;向左拖拽UISlider时,响应的是UIScrollView的拖动事件,而UISlider本身的拖拽事件也没有响应。

- 现象3 、当你长按UISlider超过150ms后直接拖拽,就不存在现象2中UISlider与UIScrollView、全屏侧滑返回的冲突问题了。

三、分析解决问题
这些问题很显然,肯定跟iOS事件的传递和响应链机制有关系,不了解的可以看看这篇文章 史上最详细的iOS之事件的传递和响应机制-原理篇。
- 分析解决问题 1
如果你了解事件的传递和响应链机制的话,应该能想到,是由于UIScrollView的内部手势方法阻断了全屏侧滑返回手势的的响应,那我们就找到这个方法,代码如下 ;
创建一个UIScrollView的类别UIScrollView+GestureConflict,重写如下方法:
//处理UIScrollView上的手势和侧滑返回手势的冲突
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
// 首先判断otherGestureRecognizer是不是系统pop手势
if ([otherGestureRecognizer.view isKindOfClass:NSClassFromString(@"UILayoutContainerView")]) {
// 再判断系统手势的state是began还是fail,同时判断scrollView的位置是不是正好在最左边
if (otherGestureRecognizer.state == UIGestureRecognizerStateBegan && self.contentOffset.x == 0) {
return YES;
}
}
return NO;
}
- 分析解决问题 2和3
方案一:这个跟UIScrollView的一个属性delaysContentTouches有关。
scrollView.delaysContentTouches = NO;
delaysContentTouches 默认值为YES 表示延迟scrollView上子视图的响应,所以当直接拖动UISlider时,如果此时touch时间在150ms以内,UIScrollView会认为是拖动自己,从而拦截了event,导致UISlider接收不到滑动的event。但是只要长按住UISlider一会儿再拖动,此时touch时间超过150ms,因此滑动的event会发送到UISlider上,然后UISlider再作出响应;设置为NO后,拖动UISlider时就可以直接做出响应,解决了UISlider与UIScrollView之间的冲突,同时也解决了向右拖拽时却触发了全屏侧滑pop返回的问题。
方案二: 重写类别UIScrollView+GestureConflict中的如下方法来解决UISlider与UIScrollView之间的冲突,然后还需要执行下面 问题补充 中的操作来处理UISlider的滑动与全屏侧滑pop返回事件的冲突。
//拦截事件的处理 事件传递给谁,就会调用谁的hitTest:withEvent:方法。
//处理UISlider的滑动与UIScrollView的滑动事件冲突
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
/*
直接拖动UISlider,此时touch时间在150ms以内,UIScrollView会认为是拖动自己,从而拦截了event,导致UISlider接受不到滑动的event。但是只要按住UISlider一会再拖动,此时此时touch时间超过150ms,因此滑动的event会发送到UISlider上。
*/
UIView *view = [super hitTest:point withEvent:event];
if([view isKindOfClass:[UISlider class]]) {
//如果接收事件view是UISlider,则scrollview禁止响应滑动
self.scrollEnabled = NO;
} else { //如果不是,则恢复滑动
self.scrollEnabled = YES;
}
return view;
}
- 问题补充
示例Demo中的UISlider是在UIScrollView上的,如果UISlider不是在UIScrollView上,而是直接就在ViewController.view上,那也就会出现拖拽UISlider时却响应了全屏侧滑pop返回手势的问题。
在支持全屏侧滑返回的UINavigationController的子类WSLNavigatioController中,遵守协议,实现如下方法:
#pragma mark -- UIGestureRecognizerDelegate
//触发之后是否响应手势事件
//处理侧滑返回与UISlider的拖动手势冲突
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
//如果手势是触摸的UISlider滑块触发的,侧滑返回手势就不响应
if ([touch.view isKindOfClass:[UISlider class]]) {
return NO;
}
return YES;
}
四、应用示例

五、项目结构

好了,俺要去鹊桥跟俺家织女相会咯✌️
iOS 全屏侧滑/UIScrollView/UISlider间滑动冲突的更多相关文章
- 原生JS实现全屏切换以及导航栏滑动隐藏及显示——重构前
思路分析: 向后滚动鼠标滚轮,页面向下全屏切换:向前滚动滚轮,页面向上全屏切换.切换过程为动画效果. 第一屏时,导航栏固定在页面顶部,切换到第二屏时,导航条向左滑动隐藏.切换回第一屏时,导航栏向右滑动 ...
- iOS - 全屏滑动
取经地址 1.使用关联 关联是指把两个对象相互关联起来,使得其中的一个对象作为另一个对象的一部分. 使用关联,是基于关键字的,因此,我们可以为任意对象增加任意多的关联,但是关键字是唯一的.关联可以保证 ...
- iOS 全屏布局
edgesForExtendedLayout属性用于替代wantsFullScreenLayout,控制页面显示的范围,默认值是UIRectEdgeAll automaticallyAdjustsSc ...
- iOS 全屏播放网页视频退出后状态栏被隐藏
使用wkWebView播放网页上的视频,播放完成后,退出视频返回到网页发现app的状态整个被隐藏了,解决方法,监听状态栏隐藏通知,在适当的时候让状态栏显示出来 [[NSNotificationCent ...
- UIScrollView的左右滑动和侧滑手势冲突的解决办法
转载自:https://blog.csdn.net/kst_123/article/details/77762811 当ViewController中添加了一个全屏的UIScrollView的时候,U ...
- iOS任何界面全屏炫酷倒计时,一句代码就够了
概述 iOS全屏炫酷倒计时,任何界面只需要调用一句代码就能实现,支持定制倒计时数字.倒计时结束时显示的文本.支持倒计时播放图片.开始倒计时和结束倒计时的block和delegate回调.支持定制文本颜 ...
- uni-app仿抖音APP短视频+直播+聊天实例|uniapp全屏滑动小视频+直播
基于uniapp+uView-ui跨端H5+小程序+APP短视频|直播项目uni-ttLive. uni-ttLive一款全新基于uni-app技术开发的仿制抖音/快手短视频直播项目.支持全屏丝滑般上 ...
- swift - 全屏pop手势
UINavigationController系统自带有侧滑手势,但是这个手势第一点只能边缘侧滑才可以有效,第二点当手动隐藏系统的导航时,这个手势就不能生效了 为了能到达到全屏pop的效果这里有2中解决 ...
- 解决微信浏览器内video全屏问题
前端离职,让我写个视频播放页面,木办法只有我来搞了. 默认用h5的 video标签 测试时候发现微信浏览器内访问video自动全屏播放. 搜了下 webkit-playsinline="tr ...
随机推荐
- USACO 2017 FEB Platinum mincross 可持久化线段树
题意 上下有两个位置分别对应的序列A.B,长度为n,两序列为n的一个排列.当Ai == Bj时,上下会连一条边.你可以选择序列A或者序列B进行旋转任意K步,如 3 4 1 5 2 旋转两步为 5 2 ...
- 51NOD 1179 最大的最大公约数 筛法
1179 最大的最大公约数 题目连接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1179 Description ...
- PAT甲级1045. Favorite Color Stripe
PAT甲级1045. Favorite Color Stripe 题意: 伊娃正在试图让自己的颜色条纹从一个给定的.她希望通过剪掉那些不必要的部分,将其余的部分缝合在一起,形成她最喜欢的颜色条纹,以保 ...
- 桥接模式:探索JDBC的接口
目录概要 场景问题 假设要设计一个电脑商场管理系统的某个模块设计,电脑分为品牌和类型两个纬度,我们应该怎么解决?我们初学者最容易想到的办法就是利用继承的方式,那利用继承实现的类图又是什么样子呢?我们看 ...
- BUZZER Driver
- JAVA-数据类型、变量、常量
http://blog.csdn.net/yuhailong626/article/details/7245571 http://www.cnblogs.com/JackieADBM/p/534222 ...
- Ant简单工程的构建
1.在Ant的官方网站http://ant.apache.org/bindownload.cgi下载Ant最新版本(我下载的是apache-ant-1.8.2-bin.zip),Ant无需安装,直接解 ...
- Codeforces Round #261 (Div. 2)[ABCDE]
Codeforces Round #261 (Div. 2)[ABCDE] ACM 题目地址:Codeforces Round #261 (Div. 2) A - Pashmak and Garden ...
- 【GISER&&Painter】Chapter01:WebGL渲染初体验
基于上一篇OpenGL的渲染原理,这两周又陆续接触了一些关于WebGL绘图的一些内容,因为刚入门,很多东西又很晦涩,所以特意花了小半天的时间整理了一下,特此记录. 零 画一个多边形吧! 把一个多边形 ...
- 浏览器User-Agent的详细信息
PC端: safari 5.1 – MACUser-Agent:Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit ...