使用 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)
使用 UIStoryBoard 语法糖的更多相关文章
- 探索C#之6.0语法糖剖析
阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...
- C#语法糖大汇总
首先需要声明的是"语法糖"这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换:而且可以提高开发编码的效率,在性能上也不会带来损失.这让java开发人员羡慕 ...
- 看看C# 6.0中那些语法糖都干了些什么(终结篇)
终于写到终结篇了,整个人像在梦游一样,说完这一篇我得继续写我的js系列啦. 一:带索引的对象初始化器 还是按照江湖老规矩,先扒开看看到底是个什么玩意. 1 static void Main(strin ...
- 看看C# 6.0中那些语法糖都干了些什么(中篇)
接着上篇继续扯,其实语法糖也不是什么坏事,第一个就是吃不吃随你,第二个就是最好要知道这些糖在底层都做了些什么,不过有一点 叫眼见为实,这样才能安心的使用,一口气上五楼,不费劲. 一:字符串嵌入值 我想 ...
- 看看C# 6.0中那些语法糖都干了些什么(上篇)
今天没事,就下了个vs2015 preview,前段时间园子里面也在热炒这些新的语法糖,这里我们就来看看到底都会生成些什么样的IL? 一:自动初始化属性 确实这个比之前的版本简化了一下,不过你肯定很好 ...
- C# 6.0新特性---语法糖
转载:http://www.cnblogs.com/TianFang/p/3928172.html 所谓语法糖就是在编译器里写做文章,达到简化代码书写的目的,要慎重使用,省略过多不易理解. NULL检 ...
- C#语法糖,让编程更具乐趣
一.什么是语法糖 语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法 ...
- Java语法糖4:内部类
内部类 最后一个语法糖,讲讲内部类,内部类指的就是在一个类的内部再定义一个类. 内部类之所以也是语法糖,是因为它仅仅是一个编译时的概念,outer.java里面定义了一个内部类inner,一旦编译成功 ...
- Java语法糖1:可变长度参数以及foreach循环原理
语法糖 接下来几篇文章要开启一个Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的 ...
随机推荐
- 初步学习jquery学习笔记(三)
jQuery学习笔记三 jquery停止动画 stop函数的初步功能 <!DOCTYPE html> <html lang="en"> <head&g ...
- SIGCHLD和wait/waipid函数的关系
SIGCHILD只是在子进程退出的时候发送给父进程的一个信号值,这是一种异步通知父进程的方式.父进程可以捕获,忽略这个信号,默认动作是忽略此信号. 常用的使用方式是,当SIGCHILD信号发生时候,主 ...
- Codeforces 1220C. Substring Game in the Lesson
传送门 首先显然的,如果 $l$ 能移动,那么 $r$ 一定可以随便移动,如果 $l$ 不动,那么 $r$ 一定不能动 那么我们现在只要考虑 $l$ 的移动即可 考虑找到位置 $k$ 之前的最左边的最 ...
- Logistic回归应用-预测马的死亡率
Logistic回归应用-预测马的死亡率 本文所有代码均来自<机器学习实战>,数据也是 本例中的数据有以下几个特征: 部分指标比较主观.难以很好的定量测量,例如马的疼痛级别 数据集中有30 ...
- 091、万能的数据收集器 Fluentd (2019-05-15 周三)
参考https://www.cnblogs.com/CloudMan6/p/7798224.html 前面的ELK 中我们使用的是 Filebeat 收集Docker日志,利用的是默认的loggi ...
- java学习笔记(5)多线程
一.简介(过段时间再写,多线程难度有点大) --------------------------------------- 1.进程:运行时的概念,运行的应用程序 2.线程:应用程序内部并发执行的代码 ...
- vue-element-ui upload组件调用两次接口
在使用upload中,默认是自动上传,会发现会调用两次接口,一次是Request Method: OPTIONS且不带任何参数(群里大佬说是跨域 预检测),一次是Request Method: POS ...
- CentOS7 yum安装配置 +redis主从配置
一.安装必要包 yum install gcc 二.linux下安装 #下载 wget http://download.redis.io/releases/redis-3.0.0.tar.gz tar ...
- jfinal layui easyexcel 实现文件的上传下载
jfinal layui easyexcel 这三样开源技术这里就不多介绍了,自行百度了解吧,他们的组合算是一个很高效又不失美观的操作体验. 操作主要分以下几步: 1.建立jfinal的操作环境, ...
- ifconfig - 配置网络接口
总览 ifconfig [接口] ifconfig 接口 [aftype] options | address ... 描述 ifconfig 用于配置常驻内核的网络接口.它用于在引导成功时设定网络接 ...