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 ...
随机推荐
- Java泛型应用总结
一.泛型的引入原因 在操作集合的时候,之前方法的定义都是Object类型,向集合中添加对象,都自动向上转型,加入的元素可以是任何类型 但是,在取出元素的时候,通常想要使用对象的特有功能,就必须向下转型 ...
- Java 请求webServce接口 带参数
public String getWebServiceByParams(String param){ //获取基金缴付记录 // Post请求的url,与get不同的是不需要带参数 URL postU ...
- Codeforces Round #245 (Div. 2) A. Points and Segments (easy) 贪心
A. Points and Segments (easy) Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/con ...
- textbox约束输入值问题解答
网上很多关于文本框只能输入数字的,今天又找了一遍,发现以前的写法居然有点问题! onkeypress="if (event.keyCode<48 || event.keyCode> ...
- Java容器-引用分类与部分Map用法
目录 1.引用分类 2.了解WeakHashMap.IdentityHashMap.EnumMap 3.同步控制与只读设置 代码实现 1.引用分类(面试) 强引用(StrongReference):引 ...
- Sublime的中文GBK显示乱码的解决方法
import urllib2,os,hashlib; h = '7183a2d3e96f11eeadd761d777e62404' + 'e330c659d4bb41d3bdf022e94cab3cd ...
- 固定的价格就意味着背叛——《practices of an agile developper》
“对这个项目,我们必须要有固定的报价.虽然我们还不清楚项目的具体情况,但仍要有一个报价.到星期一,我需要整个团队的评估,并且我们必须要在年末交付整个项目.” Venkat & Andy 提出了 ...
- highchart demo
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.c ...
- thymleaf th:if标签
1.概念 <table> <tr> <th>NAME</th> <th>PRICE</th> <th>IN STOC ...
- 2016 Top 10 Android Library
过去的 2016 年,开源社区异常活跃,很多个人与公司争相开源自己的项目,让人眼花缭乱,然而有些项目只是昙花一现,有些项目却持久创造价值,为开发者提供了极大的便利,这些终究由时间来判断.今天,我就来整 ...