zoukankan      html  css  js  c++  java
  • URL Handle in Swift (二) — 响应链处理 URL

    最后更新: 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
        }
    }
    
    
    
  • 相关阅读:
    前端之css网页布局等相关内容-54
    前端之css属性设置等相关内容-53
    前端之css选择器等相关内容-52
    前端之HTML标签等相关内容-51
    前端之HTML基础等相关内容-50
    数据库之mysql索引增删改查等相关内容-48
    累了就拥抱下自己
    平静地生活
    良心远大于失败
    独处
  • 原文地址:https://www.cnblogs.com/gaox97329498/p/11070438.html
Copyright © 2011-2022 走看看