最后更新: 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)

使用 UIStoryBoard 语法糖的更多相关文章

  1. 探索C#之6.0语法糖剖析

    阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...

  2. C#语法糖大汇总

    首先需要声明的是"语法糖"这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换:而且可以提高开发编码的效率,在性能上也不会带来损失.这让java开发人员羡慕 ...

  3. 看看C# 6.0中那些语法糖都干了些什么(终结篇)

    终于写到终结篇了,整个人像在梦游一样,说完这一篇我得继续写我的js系列啦. 一:带索引的对象初始化器 还是按照江湖老规矩,先扒开看看到底是个什么玩意. 1 static void Main(strin ...

  4. 看看C# 6.0中那些语法糖都干了些什么(中篇)

    接着上篇继续扯,其实语法糖也不是什么坏事,第一个就是吃不吃随你,第二个就是最好要知道这些糖在底层都做了些什么,不过有一点 叫眼见为实,这样才能安心的使用,一口气上五楼,不费劲. 一:字符串嵌入值 我想 ...

  5. 看看C# 6.0中那些语法糖都干了些什么(上篇)

    今天没事,就下了个vs2015 preview,前段时间园子里面也在热炒这些新的语法糖,这里我们就来看看到底都会生成些什么样的IL? 一:自动初始化属性 确实这个比之前的版本简化了一下,不过你肯定很好 ...

  6. C# 6.0新特性---语法糖

    转载:http://www.cnblogs.com/TianFang/p/3928172.html 所谓语法糖就是在编译器里写做文章,达到简化代码书写的目的,要慎重使用,省略过多不易理解. NULL检 ...

  7. C#语法糖,让编程更具乐趣

    一.什么是语法糖 语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法 ...

  8. Java语法糖4:内部类

    内部类 最后一个语法糖,讲讲内部类,内部类指的就是在一个类的内部再定义一个类. 内部类之所以也是语法糖,是因为它仅仅是一个编译时的概念,outer.java里面定义了一个内部类inner,一旦编译成功 ...

  9. Java语法糖1:可变长度参数以及foreach循环原理

    语法糖 接下来几篇文章要开启一个Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的 ...

随机推荐

  1. T2 AC自动机

    T2:AC自动机 (ac.cpp) 题目背景 YZD在每天学习20小时的勤奋研究下,终于开发出了AC自动机!但是,这台AC自动机有一些bug,比如两个部件之间经常会出一些莫名其妙的问题,所以他想要随时 ...

  2. Forsaken给学生分组

    链接:https://ac.nowcoder.com/acm/contest/1221/C来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5242 ...

  3. java 环境配置及开发工具

    1.下载JDK 网址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 2 安装jdk 3.安装好jdk后配置环境变 ...

  4. centos7 下网卡的配置

    一般通过修改配置文件的方式去修改: 网卡配置文件位置    /etc/sysconfig/network-scripts/ifcfg-ens33 DNS配置文件位置              /etc ...

  5. emmet语法列表

    emmet语法  来源:https://docs.emmet.io/cheat-sheet/ Child: > nav>ul>li <nav> <ul> &l ...

  6. 剑指offer-丑数-穷举-python

    题目描述 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 思路: ...

  7. js自执行函数

    5.1对于函数表达式,在后面加括号即可以让函数立即执行:例如下面这个函数,至于为什么加了括号就可以立即执行,我们可以这么理解,就是像fn1():这样写的话,函数 可以立即执行是没问题的,我们在经常会用 ...

  8. mybatis多对多关联关系映射

    mybatis多对多关联关系映射 多对多关系在java类实体中表示为,一个类中包含了集合为另一个类的属性.而这连个实体都需要包含对方的集合类的属性. 例如:订单和商品,一个订单包含多个商品,一个商品又 ...

  9. 教你搭建基于typescript的vue项目

    自尤大去年9月推出vue对typescript的支持后,一直想开箱尝试,对于前端sr来说,vue的顺滑加上ts的面向对象,想着就非常美好~ 终于在两个月前,找到了个机会尝试了一把vue+ts的组合. ...

  10. Docker 镜像 容器 仓库

    Docker 包括三个基本概念镜像(Image)容器(Container)仓库(Repository) Docker 镜像 Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序.库.资 ...