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 ...
随机推荐
- 使用sklearn进行交叉验证
模型评估方法 假如我们有一个带标签的数据集D,我们如何选择最优的模型? 衡量模型好坏的标准是看这个模型在新的数据集上面表现的如何,也就是看它的泛化误差.因为实际的数据没有标签,所以泛化误差是不可能直接 ...
- MYSQL学习笔记 (一)
每次面试后,都决定一改前非.事实上依然和那些发誓再吃最后一份美食的胖子一样.不管这次是不是三分钟热度但是至少我开始. MYSQL引擎 说到MYSQL引擎我又想起研二时候去面试的第一家公司 ...
- 原生+H5开发之:js交互【location方式】
1. 交互方式总结 1Android与JS通过WebView互相调用方法,实际上是: Android去调用JS的代码 JS去调用Android的代码 二者沟通的桥梁是WebView 对于Android ...
- Spring JdbcTemplate batchUpdate() 实例
在某些情况下,可能需要将一批记录插入到数据库中.如果你对每条记录调用一个插件的方法,SQL语句将被重复编译,造成系统缓慢进行. 在上述情况下,你可以使用 JdbcTemplate BATCHUPDAT ...
- MAC 更新SVN到1.8
经过谷歌和百度N次后,最终搞定SVN的升级,Intellij Idea和Xcode5.1都能够正常使用. 步骤: 1. 下载Subverion的Max安装版.(推荐.使用其它brew和port都试过, ...
- 破解NET的四大神器[转]
原本这篇文章可以更早一星期写出来与大家分享,由于某方面的原因耽搁到现在,心里竟有那么一点好像对不住大家的感觉.这当然与神器有关,因为我发现利用这四大神器我似乎觉得几乎所有的NET程序破解都不在话下了 ...
- nginx实现openfire负载均衡
Nginx版本必须是1.9以上,不然不支持tcp连接,要么加入其他插件 在nginx.conf文件中加入下图中的代码,图中的ip与端口配成自己的,配置好后,客户端请求listen监听的端口,ip为ng ...
- 【maven】maven命令 package、install、deploy 的区别
maven命令 package.install.deploy 的区别
- [转] 上级向的十个iOS面试问题
上级向的十个iOS面试问题 转自 http://onevcat.com/2013/04/ios-interview/ 不管对于招聘和应聘来说,面试都是很重要的一个环节,特别对于开发者来说,面试中的技术 ...
- 解决用户自生成meta导入kylin后报错问题Can not deserialize instance of java.lang.String[] out of VALUE_STRING token
报错栈: -- ::, ERROR [http-bio--exec-] cube.CubeManager: : Error during load cube instance, skipping : ...