iOS7下滑动返回与ScrollView共存

Windows Phone 7 Panorama中枢设计:信息架构与MVVM轻量化实践 Panorama是Windows Phone 7提出的一种空间化信息组织范式,本质并非滑动容器,而是通过水平延展、视觉引导与内容隔离构建用户认知路径;其设计原理直指移动端核心命题——在有限屏幕与低性能设备上实现高信息密度与高操作效率的平衡。该模式依托MVVM实现松耦合,但摒弃教条框架,采用按需通知、Insert(0)置顶、TwoWay绑定等轻量化落地策略,显著提升响应性与可维护性。技术价值在于以空间换时间、用平台原生能力替代算力堆砌,适用于Xamarin、Flutter及现代跨平台教育类应用的信息中枢重构。 阅读详情

【前情回顾】

去年的时候,写了这篇帖子iOS7滑动返回。文中提到,对于多页面结构的应用,可以替换interactivePopGestureRecognizer的delegate以统一管理应用中所有页面滑动返回的开关,比如在UINavigationController的派生类中

复制代码
 1 //我是一个NavigationController的派生类
 2 - (id)initWithRootViewController:(UIViewController *)rootViewController
 3 {
 4     self = [super initWithRootViewController:rootViewController];
 5     if (self)
 6     {
 7         //在naviVC中统一处理栈中各个vc是否支持滑动返回的情况
 8         //当前仅最底层的vc关闭滑动返回
 9         self.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;
10     }
11     
12     return self;
13 }
复制代码

然后在委托中控制滑动返回的开关

复制代码
 1 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
 2 {
 3     if (self.viewControllers.count == 1)//关闭主界面的右滑返回
 4     {
 5         return NO;
 6     }
 7     else
 8     {
 9         return YES;
10     }
11 }
复制代码

 

【问题所在】

看上去挺美好的。。。。直到遇到了ScrollView。

替换了delegate后,在使用时ScrollView,在屏幕左边缘就无法触发滑动返回效果了,如图

 

【问题原因】

滑动返回事实上也是由存在已久的UIPanGestureRecognizer来识别并响应的,它直接与UINavigationController的view(方便起见,下文中以UINavigationController.view表示)进行绑定,因此上图中存在如下关系:
UIPanGestureRecognizer          ——bind——  UIScrollView

UIScreenEdgePanGestureRecognizer ——bind——  UINavigationController.view

滑动返回无法触发,说明UIScreenEdgePanGestureRecognizer并没有接收到手势事件。

 

根据apple君的官方文档,UIGestureRecognizer和UIView是多对一的关系(具体点这里),UIGestureRecognizer一定要和view进行绑定才能发挥作用。因此不难想象,UIGestureRecognizer对于屏幕上的手势事件,其接收顺序和UIView的层次结构是一致的。同样以上图为例

 

(我是Z轴)-------------------------------------------------------------------------------------------------------------------------------------->

 

UINavigationController.view —>  UIViewController.view —>  UIScrollView —>  Screen and User's finger

 

即UIScrollView的panGestureRecognizer先接收到了手势事件,直接就地处理而没有往下传递。

 

实际上这就是两个panGestureRecognizer共存的问题。

 

【解决方案】

苹果以UIGestureRecognizerDelegate的形式,支持多个UIGestureRecognizer共存。其中的一个方法是:

复制代码
1 // called when the recognition of one of gestureRecognizer or otherGestureRecognizer would be blocked by the other
2 // return YES to allow both to recognize simultaneously. the default implementation returns NO (by default no two gestures can be recognized simultaneously)
3 //
4 // note: returning YES is guaranteed to allow simultaneous recognition. returning NO is not guaranteed to prevent simultaneous recognition, as the other gesture's delegate may return YES
5 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
复制代码

 一句话总结就是此方法返回YES时,手势事件会一直往下传递,不论当前层次是否对该事件进行响应。

 

看看UIScrollView的头文件,有如下描述:

1 // Use these accessors to configure the scroll view's built-in gesture recognizers.
2 // Do not change the gestures' delegates or override the getters for these properties.
3 @property(nonatomic, readonly) UIPanGestureRecognizer *panGestureRecognizer NS_AVAILABLE_IOS(5_0);

UIScrollView本身是其panGestureRecognizer的delegate,且apple君明确表明不能修改它的delegate(修改的时候也会有警告)。

那么只好曲线救国。

UIScrollView作为delegate,说明UIScrollView中实现了上文提到的shouldRecognizeSimultaneouslyWithGestureRecognizer方法,返回了NO。创建一个UIScrollView的category,由于category中的同名方法会覆盖原有.m文件中的实现,使得可以自定义手势事件的传递,如下:

复制代码
 1 @implementation UIScrollView (AllowPanGestureEventPass)
 2 
 3 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
 4 {
 5     if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]
 6         && [otherGestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]])
 7     {
 8         return YES;
 9     }
10     else
11     {
12         return  NO;
13     }
14 }
复制代码

再次运行demo,看看效果:

嗯,滑动返回已经成功触发,鼓掌!

等会等会。。。

好像不太对。。。

scrollView怎么也滚动了!!!!!

O。。。只是做到了将手势事件往下传递,而没有关闭掉在边缘时UIScrollView对事件的响应。

 

事实上,对UIGestureRecognizer来说,它们对事件的接收顺序和对事件的响应是可以分开设置的,即存在接收链和响应链。接收链如上文所述,和UIView绑定,由UIView的层次决定接收顺序。

而响应链在apple君的定义下,逻辑出奇的简单,只有一个方法可以设置多个gestureRecognizer的响应关系:

// create a relationship with another gesture recognizer that will prevent this gesture's actions from being called until otherGestureRecognizer transitions to UIGestureRecognizerStateFailed
// if otherGestureRecognizer transitions to UIGestureRecognizerStateRecognized or UIGestureRecognizerStateBegan then this recognizer will instead transition to UIGestureRecognizerStateFailed
// example usage: a single tap may require a double tap to fail
- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;

每个UIGesturerecognizer都是一个有限状态机,上述方法会在两个gestureRecognizer间建立一个依托于state的依赖关系,当被依赖的gestureRecognizer.state = failed时,另一个gestureRecognizer才能对手势进行响应。

 

所以,只需要

[_scrollView.panGestureRecognizer requireGestureRecognizerToFail:screenEdgePanGestureRecognizer];

即可。

 

再次运行demo,看看效果:

 Works like a Charm!!

 

P.S:screenEdgePanGestureRecognizer是和UINavigationController.view绑定的,因此可以遍历UINavigationController.view.gestureRecognizers来获取,如下:

复制代码
- (UIScreenEdgePanGestureRecognizer *)screenEdgePanGestureRecognizer
{
    UIScreenEdgePanGestureRecognizer *screenEdgePanGestureRecognizer = nil;
    if (self.view.gestureRecognizers.count > 0)
    {
        for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers)
        {
            if ([recognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]])
            {
                screenEdgePanGestureRecognizer = (UIScreenEdgePanGestureRecognizer *)recognizer;
                break;
            }
        }
    }

    return screenEdgePanGestureRecognizer;
}
复制代码

 


demo地址:https://github.com/cDigger/CoExistOfScrollViewAndBackGesture/tree/master

 

【总结】

写了这么多,只是为了最初统一管理滑动返回的一点点便利,似乎很有些得不偿失。

我并不建议直接在项目中使用这种非常规手段。

但使用apple君提供的积木,自己拼出系统中的新功能,也是iOS开发的乐趣之一啊。


转:http://www.cnblogs.com/lexingyu/p/3702742.html

智能车竞赛新手必看:用AD21从零画一块英飞凌TC264核心板(附开源PCB文件) 本文详细介绍了使用Altium Designer 21(AD21)从零开始设计英飞凌TC264核心板的完整流程,涵盖原理图绘制、PCB布线到最终DRC检查的全过程。针对智能车竞赛新手,提供了实用的硬件设计技巧和开源PCB文件,帮助快速掌握TC264核心板开发。 阅读详情

相关推荐

电信光猫隐藏的VOIP功能揭秘:不用座机也能打电话(EasySip实战)

本文揭秘了电信光猫隐藏的VOIP功能,通过EasySip实战演示如何无需座机实现高清通话。详细解析了光猫的SIP协议支持、语音VLAN配置及网络架构优化,帮助用户利用现有设备提升通话质量并扩展设备兼容性,特别适合智能家居和企业级应用场景。

weixin_29268385的博客 754

嵌套UIScrollview的滑动冲突解决方案

虽然苹果建议我们不要嵌套 UIScrollview ,但是这话到底是对开发者说的,架不住设计师就是要这么画设计图。我遇到的场景类似这样,顶部有一个优先展示的封面,当封面滚出屏幕后下面内容的 ScrollView 开始滚动。因为介绍、目录、评价三个tab是可以左右滚动的,所以具体内容是嵌套在一个 ScrollView 里的。 但是其实面临的问题都是相似的,嵌套了 ScrollView 后,需要一...

weixin_34032621的博客 1377

weblogic 集群搭建,双机部署,相关问题记录

4.5.集群搭建1 参考网址https://wenku.baidu.com/view/76365129cd1755270722192e453610661ed95aa4.html IP地址 端口 角色 192.168.1.160 9001 AdminServer ...

zl386119974的专栏 1669

Android系统镜像定制:从system.img到vendor.img的快速修改与打包实践

Android系统镜像定制是移动设备深度个性化与系统优化的核心技术。其原理基于对Android分区架构的深入理解,特别是system.img、vendor.img等核心镜像文件的解包、修改与重打包流程。这项技术的核心价值在于能够实现系统级功能的增删改,例如移除预装应用、集成Magisk实现系统级Root、修改系统属性与功能开关等,广泛应用于ROM定制、设备调试与性能优化等场景。通过构建自动化工具链,开发者可以高效处理sparse image转换、ext4文件系统操作以及SELinux策略配置,实现从“手工作

weixin_33910385的博客 417

共享单车数据分析与需求预测项目

除了自行车共享系统的有趣的实际应用之外,这些系统生成的数据特征使它们成为研究的有吸引力的对象。由于这些系统在交通、环境和健康问题中的重要作用,它们引起了极大的关注。Huber 回归器:一个对异常值具有鲁棒性的模型,CV 得分为 0.4660,表明它对此数据集可能不那么有效。代码中的内容cv_score就像您正在使用的机器学习模型的成绩单。它告诉您模型的表现如何。减少异常值的影响:它还可以减少异常值的影响,因为对数转换显着缩小了数据的范围。因此,cv_score平均分数表明您的模型的预测效果如何。

极光喵的博客 2944

JLINK/SWD/STLINK下载选项区别

摘要: 本文对比了JLINK/SWD/STLINK的6种下载模式:Normal(硬件复位)、Hot plug(无复位)、Under reset(持续复位后连接)、Software reset(软件复位)、Hardware reset(全复位)和Core reset(内核复位)。重点分析了各模式的操作逻辑、适用场景及注意事项,其中Under reset模式是解决SWD禁用/程序异常的首选方案。通过对比表归纳了复位范围、NRST操作等核心差异,并给出场景选择建议:排查连接问题优先选Under reset,常规调

亚洲程序员盟主得博客 394

UIScrollView(滚动试图)

UIScrollView(滚动试图) 1.简介 为什么有UISCrollView: 在iOS开发中,由于移动设备的屏幕大小有限,所以不能像PC一样显示很多内容,因此当手机屏幕需要展示的内容较多超出一个屏幕时,用户可以通过滚动手势来查看屏幕以外的内容。 普通的UIView不具备滚动的功能的,Apple公司就封装了一个继承于UIView的UIScrollView类(@interface...

weixin_30593261的博客 193

11.Labview实现用户界面切换的几种方式---通过VI间相互调用

本文介绍了界面切换的几种方式,分别是重入和引用①重入方式可以通过调用子VI的方式打开被调用的界面,往往应用于弹窗等的设置程序。②引用方式分两种,一种是打开引用,一种是静态引用。区别在于打开引用需要设置被打开VI的目标地址,静态引用仅需在引用时绑定VI的位置即可。③推荐使用静态引用的方式切换界面。④使用引用打开界面时,需通过属性节点和调用节点来设置程序的状态。更多内容欢迎大家补充和留言讨论~本文介绍了GUI界面设计相关的程序,更多相关文章后续持续更新,请关注作者不迷路~本期就到这里,再见~

关注我,更多技术问题欢迎私聊~ 9542

UIScrollView

UIScrollView是一个可以滚动的继承于UIView的控件:如果直接在StoryBoard上面拉上一个UIScrollView控件.就是个这么情况.正常的SB(StoryBoard)的使用方式是:1.先拖上来一个UIScrollView控件.然后设置一下约束:Update Frames那里选择Item of New Constraints主要是为了图省事.2.注意.我们这里的顶部是相对于最上...

MeteoriteMan的博客 483

Word2vec核心模型精讲:CBOW与Skip-gram

Word2vec是Google提出的词向量模型,通过CBOW和Skip-gram两种神经网络架构将词汇映射到低维向量空间。CBOW通过上下文预测中心词,训练速度快但高频词表现更好;Skip-gram则相反,通过中心词预测上下文,适合处理生僻词。为解决softmax计算效率问题,Word2vec引入基于哈夫曼树的Hierarchical Softmax优化技术,将复杂度从O(V)降至O(logV)。文章详细解析了两种模型的原理差异,并演示了哈夫曼树的构造过程及其在词向量训练中的关键作用,这种结合词频的优

Trisyp的博客 528

超级全的PCB LAYOUT高速信号走线指南——简化应用版

在PCB Layout中,几乎涵盖了所有的高速信号走线指南。包括了TF/SD、HDMI、LVDS、DVP、eDP、MIPI、USB2.0、USB3.0、MAC、BT.1120、PCIE高速信号等等。此版本为简化版。

bhxc809751502的博客 8546

iOS中分页视图滚动和全屏返回手势冲突的问题

1 我们这个页面是一个左右分页的容器页面,可以左右滚动分页,然后app整体之前是支持右滑返回的,这样就遇到一个问题,就是我们在分页的最左边的时候,滑动的时候,因为分页的scrollView的滑动手势是在最上层的左右滑动手势,所以,在自然情况下,我们滑动的时候,是响应scrollView的滑动手势的,不会响应navigationController的滑动返回的手势如何让系统响应返回手势呢,这就用到了。

liubo的博客 861

端侧 AI 落地避坑指南(中):为什么 QAT 救不了精度?——对齐“融合后算子“的硬件物理约束

在上一篇文章中,我们深入探讨了量化的本质,并得出结论:QAT(量化感知训练)是保持精度的关键。明明做了 QAT,精度还是崩塌了!让我们看一个真实的案例:✅ 使用了✅ 配置了量化✅ 训练了 50 个 epoch,学习率降为原来的 1/10✅ 冻结了 BN 统计量FP32 模型:mAP = 0.85QAT 后 FP32:mAP = 0.84(正常)工具量化后:mAP = 0.68(崩塌!问题出在哪里?层融合(Layer Fusion)机制。

weixin_51988935的博客 55

iOS7下滑动返回与ScrollView共存二三事

iOS7下滑动返回与ScrollView共存二三事   【前情回顾】 去年的时候,写了这篇帖子iOS7滑动返回。文中提到,对于多页面结构的应用,可以替换interactivePopGestureRecognizer的delegate以统一管理应用中所有页面滑动返回的开关,比如在UINavigationController的派生类中 1 //我是一个Navigatio

happyrabbit456的专栏 802

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

ios7 侧滑返回

前言: ios7开始 苹果增加了页面 右滑返回的效果;具体的是以UINavigationController为容器的ViewController间右滑切换页面。 代码里的设置是: self.navigationController.interactivePopGestureRecognizer.enabled = YES;(default is YES) 可以看到苹果给navigation

Anthony_mao的博客 459

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

ios7侧滑返回

转载自:http://blog.sina.com.cn/s/blog_65c178a80102v0f4.html 前言: ios7开始 苹果增加了页面 右滑返回的效果;具体的是以UINavigationController为容器的ViewController间右滑切换页面。 代码里的设置是: self.navigationController.interactivePo

gdutxzy的专栏 946

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

iOS 下实现侧滑返回效果

前言: ios7开始 苹果增加了页面 右滑返回的效果;具体的是以UINavigationController为容器的ViewController间右滑切换页面。 代码里的设置是: self.navigationController.interactivePopGestureRecognizer.enabled = YES;(default is YES) 可以看到苹果给navigation

Yashon 2072

iOS 7 导航栏返回

前言:ios7开始 苹果增加了页面 右滑返回的效果;具体的是以UINavigationController为容器的ViewController间右滑切换页面。代码里的设置是: self.navigationController.interactivePopGestureRecognizer.enabled = YES;(default is YES) 可以看到苹果给navigationCont...

weixin_30784501的博客 125

侧滑返回---UIScrollView

转载自http://www.cnblogs.com/lexingyu/p/3702742.html   【前情回顾】 去年的时候,写了这篇帖子iOS7滑动返回。文中提到,对于多页面结构的应用,可以替换interactivePopGestureRecognizer的delegate以统一管理应用中所有页面滑动返回的开关,比如在UINavigationController的派

Nero的专栏 1537

iOS 手势识别器深度解析:手势原理、冲突根源、优先级控制

本文深入解析iOS手势识别机制及常见冲突解决方案。首先指出手势识别在开发中的核心地位及常见问题,如手势冲突、失效等,根源在于开发者对手势底层机制理解不足。文章从手势与触摸事件的层级关系切入,揭示手势识别器优先级高于控件原生事件和原始触摸响应的铁律。 核心内容包括六大系统手势特性分析、三大冲突根源(独占机制、Pan手势高优先级、手势与控件互斥)及解决方案。

linwenglong7155的博客 402

iOS秋招全攻略:从内存管理到面试实战的硬核经验

内存管理、多线程与RunLoop是iOS开发的基石,也是面试官高频考察的技术要点。理解引用计数、GCD队列、RunLoop运行模式等底层原理,不仅能解决循环引用、列表卡顿等实际工程问题,更是评估开发者技术深度的关键标尺。从AutoreleasePool的释放时机到NSOperation与GCD的适用场景,这些基础概念贯穿于性能优化、图片缓存、网络层设计等常见业务需求之中。本文作者结合自身四十余场iOS秋招面试经历,系统梳理了简历准备、复习资料取舍、高频八股文、项目深挖技巧、算法题策略、系统设计思路及HR面沟

weixin_34095889的博客 354

android 面试题

ContextImpl.startActivity → Instrumentation.execStartActivity → AMS.startActivity → 校验权限、创建 ActivityRecord、Pause 当前 Activity → ApplicationThread.scheduleTransaction → ActivityThread.H → LaunchActivityItem → performLaunchActivity(创建 Activity、调用 onCreate)。

qq_25657125的博客 388

面试题kkk

这篇文章摘要主要涵盖了Android开发中的核心知识点和技术难点,包括数据结构、Java与Kotlin语言特性、多线程与并发、内存管理、安卓组件与UI、IPC通信、数据库、多媒体处理、设计模式、性能优化、跨端开发等多个方面。文章详细解析了常见数据结构的使用与实现、JVM机制、内存泄漏分析与解决方案、Activity生命周期、事件分发机制、Handler原理、音视频处理、设计模式应用等核心内容,并提供了实际项目中的技术卡点与解决方案。此外,还涉及了性能优化策略、跨端开发差异、技术方案设计思路以及Git常用命令

mix39的博客 928

iOS 侧滑返回手势与Scrollview冲突的解决办法

苹果在iOS7.0以后推出了一个侧滑返回手势,当导航栏Push到下一页时,可以通过侧滑手势pop到上一页,这大大提高了用户的体验度,同时增加了可玩性。 然而有些时候,当你push到另一个界面后,如果该界面有Scrollview或继承于Scrollview(tableview,collectionview)的控件,这时你可能会发现返回手势失效了,这个是为什么喃? 经过我多番验证,原来是这个控件拦截...

gcs的博客 4162

手势冲突---UITableView删除, 自定义侧滑返回,UIScroll的手势冲突

返回手势和UITableView删除的冲突 今天遇到一个手势冲突的问题在这里记录一下 由于还要适配ios6 所以就从网上找了个侧滑返回的类 MLNavigationController 但是这个类手势和UITableView的滑动删除是有冲突的 所以UITableView的手势被干掉了(原生的UINavigationcontroller不会) 冲突项目在这里 解决办法就是写个scr

Nero的专栏 4726
上一篇: iOS7滑动返回
下一篇: iOS10适配—注册推送错误:Code=3000
直隶码农
博客等级 码龄19年 95粉丝 103原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值