最后更新: Swift4时候的博客,以前在 CMD markdown 上编辑的,现在搬到这里

更新日期: 2018-06-06

上篇文章-URL Handle in Swift (一) -- URL 分解中,我们已经将URL进行了分解, 信息全部保存在了IGInstruction类型之中. 在这篇文章之后, 我们将讨论如何构建一个类似iOS响应者链来处理IGInstruction

一、响应者链

iOS响应者链相关的知识在网络上一大把。 这里我就简单的说明一下。 UIApplicationUIViewUIViewController 继承于 UIResponder, UIResponder中有一个 next, 表示在响应者链上的下一个响应者。

  1. UIApplication.nextnil

  2. UIWindow.nextUIApplication, UIView.nextSuperView 或者 UIViewController;

  3. UIViewController.next 情况就比较的复杂了:

  • UIWindow.rootViewController.next 为 UIWindow`;

  • 通过 present(, animated:, completion:)出来的 VC, nextpresentedViewController;

  • 通过 navigationController?.pushViewController(, animated:)出来的 出来的 VC, nextnavigationController;

  • UITabbarController管理的 viewControllers, nextUITabbarController;

  • UIPageViewController管理的 viewControllers, nextUIPageViewController;

在处理 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
}
}

最新文章

  1. Android Studio一些常用快捷键及快捷键冲突解决
  2. Firebug 学习使用教程
  3. ssm+redis 如何更简洁的利用自定义注解+AOP实现redis缓存
  4. 已解决: 已引发: "无法加载 DLL“opencv_core2410”: 找不到指定的模块。
  5. Java问题总结
  6. 【python】进程
  7. 关于php多线程的记录
  8. UIView的剖析(转)
  9. android开发实现静默安装(root权限)
  10. BINARY and varBINARY
  11. 【转】伟大的RAC和MVVM入门(一)
  12. Android开发周报:Android L默认加密用户数据
  13. Interrupts
  14. HTML的基本结构与标签的初步了解
  15. Mysql数据库查询不区分大小写解决方案
  16. 运用正则+replace+substring将一段英语的字母大写 angurlar运用自定义指令filter完成首字母大写
  17. jinji2
  18. 【题解】Luogu P2057 [SHOI2007]善意的投票
  19. 一个DRAM的存储单元存储的是0还是1取决于电容是否有电荷,有电荷代表1,无电荷代表0。
  20. 统计方法运行时间【Java实现】

热门文章

  1. ubuntu运行android studio出错unable to run mksdcard sdk tool
  2. CodeForces 605 E. Intergalaxy Trips
  3. Bzoj2882 工艺 [线性算法]
  4. SQL触发器的使用及语法
  5. c language compile process.
  6. hdu 3061 hdu 3996 最大权闭合图 最后一斩
  7. AndroidStudio不重新运行,Debug调试已有进程
  8. Cryptography I 学习笔记 --- 基于Diffie-Hellman的公钥加密
  9. Network | TCP
  10. 2016北京集训测试赛(十七)Problem A: crash的游戏