zoukankan      html  css  js  c++  java
  • 使用 UIStoryBoard 语法糖

    最后更新: 2018-09-06

    当你用 UIStoryBoard (以下简称 'SB') 做iOS开发时候,总是避免不了设置 StoryBoard ID 的问题, StoryBoard ID 是一个字符串,这种硬编码的形式如果时间久远,就很容易忘记, 也容易导致拼写的错误。 我们常常使用最简单的复制、粘贴的形式来保证一致,但是偶尔也会出现那种失误性的新增或者删除。而当 SB 大到一定的规模,打开 SB 查找对应的 StoryBoard ID 的卡顿也是难以忍受的。

    我希望在我运行的时候,编辑器能帮忙检查此类,尽可能减少错误的信息。类似这种:

    UIStoryboard.main.instantiateViewController(withIdentifier: .SecondViewController)
    

    以下是我的实现详情:

    1. StoryboardInitializable

    StoryboardInitializable 是初始化 StoryBoard 所必须的,它需要一个 name 以及 bundle. 大多时候 bundle 默认为 nil

    protocol StoryboardInitializable {
        
        static var name: String { get }
        
        static var bundle: Bundle? { get }
    }
    
    extension StoryboardInitializable {
        static var bundle: Bundle? {
            return nil
        }
    }
    

    2. IDConvertible

    当实例化一个控制器的时候,就需要使用到对应的 StoryBoard ID ,我们需要让编辑器知道检查对应的类型。

    protocol IDConvertible {
        
        associatedtype IDIdentity
    }
    
    

    3. ControllerInitializable

    这里是实例化控制器的协议,提供了系统默认的两个方法以及自定义的一个,提供类似原生的使用效果。

    
    protocol ControllerInitializable: StoryboardInitializable, IDConvertible {
        
        func instantiateInitialViewController() -> UIViewController?
        
        func instantiateViewController(withIdentifier identifier: Self.IDIdentity) -> UIViewController
        
        func instantiateViewController(withIdentifier identifier: String) -> UIViewController
    }
    
    extension ControllerInitializable {
        
        func instantiateInitialViewController() -> UIViewController? {
            return UIStoryboard(name: Self.name, bundle: Self.bundle).instantiateInitialViewController()
        }
    }
    
    extension ControllerInitializable where IDIdentity: RawRepresentable, IDIdentity.RawValue == String {
        
        func instantiateViewController(withIdentifier identifier: Self.IDIdentity) -> UIViewController {
            return instantiateViewController(withIdentifier: identifier.rawValue)
        }
        
        func instantiateViewController(withIdentifier identifier: String) -> UIViewController {
            return UIStoryboard(name: Self.name, bundle: Self.bundle).instantiateViewController(withIdentifier: identifier)
        }
        
    }
    
    extension ControllerInitializable where IDIdentity == String {
        
        func instantiateViewController(withIdentifier identifier: Self.IDIdentity) -> UIViewController {
            return UIStoryboard(name: Self.name, bundle: Self.bundle).instantiateViewController(withIdentifier: identifier)
        }
    }
    
    

    4. StringConvertible

    从 SB 中实例化 UIViewController 需要提供对应的 StoryBoardID, 此处提供一个 转换为 String 的协议。

    protocol StringConvertible {
        var string: String  { get }
    }
    
    extension ControllerInitializable where IDIdentity: StringConvertible {
        
        func instantiateViewController(withIdentifier identifier: Self.IDIdentity) -> UIViewController {
            return instantiateViewController(withIdentifier: identifier.string)
        }
        
        func instantiateViewController(withIdentifier identifier: String) -> UIViewController {
            return UIStoryboard(name: Self.identifier, bundle: Self.bundle).instantiateViewController(withIdentifier: identifier)
        }
    }
    
    

    给 UIStoryboard 做对应的扩展

    extension UIStoryboard {
        
        static var main: UIStoryboard.Main {
            return Main()
        }
        
        public struct Main: ControllerInitializable {
    
            typealias IDIdentity = EnumIdentifier
            
            static var name: String { return "Main"}
            
            public enum EnumIdentifier: String {
                case SecondViewController
                case OtherViewController
            }
        }
    
    }
    
    

    使用方法:

     UIStoryboard.main.instantiateViewController(withIdentifier: .SecondViewController)
    
  • 相关阅读:
    谈谈 OC 中的内联函数
    Spring 新手教程(二) 生命周期和作用域
    实时竞价(RTB) 介绍(基础篇)
    oracle数据库性能优化方案精髓整理收集回想
    HNU 13411 Reverse a Road II(最大流+BFS)经典
    CSS3主要知识点复习总结+HTML5新增标签
    修改默认MYSQL数据库data存放位置
    mysql状态查看 QPS/TPS/缓存命中率查看
    Mysql5.7.10新加用户
    很靠谱linux常用命令
  • 原文地址:https://www.cnblogs.com/gaox97329498/p/11915632.html
Copyright © 2011-2022 走看看