URL Handle in Swift (二) — 响应链处理 URL
最后更新: Swift4时候的博客,以前在 CMD markdown 上编辑的,现在搬到这里
更新日期: 2018-06-06
在上篇文章-URL Handle in Swift (一) -- URL 分解中,我们已经将URL进行了分解, 信息全部保存在了IGInstruction类型之中. 在这篇文章之后, 我们将讨论如何构建一个类似iOS响应者链来处理IGInstruction。
一、响应者链
iOS响应者链相关的知识在网络上一大把。 这里我就简单的说明一下。 UIApplication、UIView、UIViewController 继承于 UIResponder, UIResponder中有一个 next, 表示在响应者链上的下一个响应者。
UIApplication.next为nilUIWindow.next为UIApplication,UIView.next为SuperView或者UIViewController;UIViewController.next情况就比较的复杂了:
UIWindow.rootViewController.next 为 UIWindow`;
通过
present(, animated:, completion:)出来的VC,next为presentedViewController;通过
navigationController?.pushViewController(, animated:)出来的 出来的VC,next为navigationController;UITabbarController管理的viewControllers,next为UITabbarController;UIPageViewController管理的viewControllers,next为UIPageViewController;
在处理 URL 过程中, 我们也仅仅需要考虑找到合适的 Responder, 然后执行响应的操作。实际上, 我们还可以简化一点, 因为在实际的开发中, 当接收到一个 URL, 最常见的就是弹出一个对应的控制器来进行操作。
二、寻找合适 Responder
首先定义一个 IGNode 协议,
import Foundation
public enum IGHandlerAction {
case ignoring
case handling(()->Void)
}
protocol IGHandlerable {
func handler(forIns instruction: IGInstruction) -> IGHandlerAction
}
extension IGHandlerAction {
@discardableResult
public func handle() -> Bool {
switch self {
case .handling(let handler):
handler()
default:
break
}
return self.isHandling
}
public var isHandling: Bool {
switch self {
case .handling(_):
return true
case .ignoring:
return false
}
}
public var hasAction: Bool {
switch self {
case .handling(_):
return true
default:
return false
}
}
}
protocol IGNode {
var igHanderable: IGHandlerable? { get }
var firstIGNode: IGNode { get }
var nextIGNode: IGNode? { get }
func handlerInChain(forIG instruction: IGInstruction, fromFirstNode: Bool) -> IGHandlerAction
}
extension IGNode where Self: UIResponder {
var nextIGNode: IGNode? {
var next = self.next
while next != nil {
if let node = next as? IGNode {
return node
}
next = next?.next
}
return nil
}
}
extension IGNode {
func handlerInChain(forIG instruction: IGInstruction, fromFirstNode: Bool) -> IGHandlerAction {
if fromFirstNode {
return self.firstIGNode.handlerInChain(forIG: instruction, fromFirstNode: false)
} else {
if let action = self.igHanderable?.handler(forIns: instruction), action.isHandling {
return action
} else {
return self.nextIGNode?.handlerInChain(forIG: instruction, fromFirstNode: false) ?? .ignoring
}
}
}
var firstIGNode: IGNode { return self }
}
UIViewController + IGNode
extension UIViewController: IGNode {
var igHanderable: IGHandlerable? {
return !self.ignoreIG ? (self as? IGHandlerable) : nil
}
@objc open var ignoreIG: Bool { return self.presentedViewController != nil }
var firstIGNode: IGNode {
if let presented = self.presentedViewController {
return presented.firstIGNode
} else {
return currentChildViewController?.firstIGNode ?? self
}
}
@objc open var currentChildViewController: UIViewController? {
return nil
}
}
extension UINavigationController {
@objc open override var currentChildViewController: UIViewController? {
return self.topViewController
}
}
extension UITabBarController {
@objc open override var currentChildViewController: UIViewController? {
return self.selectedViewController
}
}
extension UIPageViewController {
@objc open override var currentChildViewController: UIViewController? {
return self.viewControllers?.first ?? self
}
}
URL Handle in Swift (二) — 响应链处理 URL的更多相关文章
- URL Handle in Swift (一) -- URL 分解
更新时间: 2018-6-6 在程序开发过程之中, 我们总是希望模块化处理某一类相似的事情. 在 ezbuy 开发中, 我接触到了对于 URL 处理的优秀的代码, 学习.改进.记录下来.希望对你有所帮 ...
- thinkPHP四种URL访问方式(二)
原文:thinkPHP四种URL访问方式(二) 四.url的4种访问方式 1.PATHINFO 模式 -- (重点) http://域名/项目名/入口文件/模块名/方法名/键1/值1/键2/ ...
- iOS 获取当前响应链的First Responder (Swift)
import UIKit private weak var currentFirstResponder: AnyObject? extension UIResponder { static func ...
- iOS 响应链
一.UIResponder app 使用响应者对象接收和处理事件,只有继承 UIResponder 的类,才能处理事件. UIApplication.UIView.UIViewController 都 ...
- 追踪app崩溃率、事件响应链、Run Loop、线程和进程、数据表的优化、动画库、Restful架构、SDWebImage的原理
1.如何追踪app崩溃率,如何解决线上闪退 当 iOS设备上的App应用闪退时,操作系统会生成一个crash日志,保存在设备上.crash日志上有很多有用的信息,比如每个正在执行线程的完整堆栈 跟踪信 ...
- 事件分发&响应链
iOS的三种事件:触摸事件/运动事件/远程控制事件 typedef enum { UIEventTypeTouches, UIEventTypeMotion, UIEventTypeRemoteCon ...
- iOS-UIResponse之事件响应链及其事件传递
UIResponse之事件响应链及其事件传递 我们的App与用户进行交互,基本上是依赖于各种各样的事件.一个视图是一个事件响应者,可以处理点击等事件,而这些事件就是在UIResponder类中定义的. ...
- 设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型)
设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就 ...
- iOS开发 - 事件传递响应链
序言 当我们在使用微信等工具,点击扫一扫,就能打开二维码扫描视图.在我们点击屏幕的时候,iphone OS获取到了用户进行了“单击”这一行为,操作系统把包含这些点击事件的信息包装成UITouch和UI ...
随机推荐
- jquery 实践操作:attr()方法
此篇要记录的是 关于 jquery 的 attr() 方法 在JS中设置节点的属性与属性值用到setAttribute(),获得节点的属性与属性值用到getAttribute(),而在jquery中 ...
- 洛谷 [P2577] 午餐
DP + 贪心 我们发现,如果只有一个窗口,贪心即可解决,吃饭时间长的人一定要先打饭 有两个窗口的时候,这条性质依然满足,但是两个窗口如何分配,需要 01 背包 #include <iostre ...
- java 去html标签,去除字符串中的空格,回车,换行符,制表符
public static String getonerow(String allLine,String myfind) { Pattern ...
- Codeforces Gym101473 A.Zero or One (2013-2014 ACM-ICPC Brazil Subregional Programming Contest)
代码: #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #i ...
- FZU 1075 分解素因子【数论/唯一分解定理/分解素因子裸模板】
[唯一分解定理]:https://www.cnblogs.com/mjtcn/p/6743624.html 假设x是一个正整数,它的值不超过65535(即1<x<=65535),请编写一个 ...
- Unity工程资源破解
Unity工程资源提取其实还是很方便的,网上也有很多相关介绍,比如雨凇就专门写了一遍关于破解Unity资源的文章(http://www.xuanyusong.com/archives/3618 ...
- SecureCRT双击Tab快速复制Session
- f5压缩
F5应用加速 编辑 F5在4个方面对Web应用提速: 一降低网络传输的压力,最典型技术是压缩 F5的加速技术把100K的页面压缩到20K在广域网上传输,一些标准的浏览器如IE.火狐可以自动解压,这一过 ...
- iOS 5 does not allow to store downloaded data in Documents directory? ios5.0及以后的版本对于下载的文件存储路径有了改变
I have made an application for my client by keeping target iOS as 4. But since the application still ...
- Android开发常见的Activity中内存泄漏及解决办法
上一篇文章楼主提到由Context引发的内存泄漏,在这一篇文章里,我们来谈谈Android开发中常见的Activity内存泄漏及解决办法.本文将会以“为什么”“怎么解决”的方式来介绍这几种内存泄漏. ...