凡是维护过中型项目的iOS工程师都应该有过相似的体验:ViewController
代码繁重、功能复杂、维护困难,整个工程寥寥几个ViewController
就完成了整个项目的开发。每一个控制器中都囊括了全部的页面布局、委托代理、网络请求、数据库操做和核心功能,这样的代码每每问题重重,修改起来牵一发而动全身,着实使人头疼。php
为了应对这一系列的问题,苹果公司的工程师给咱们提供了不少选择去更好的在项目工程中贯彻MVC
的设计理念,例如使用从前的Interface Builder
制做xib
可视布局,如今已经内置到xcode
里面,而且提供了更为强大Storyboard
功能,来减小控制器
中的页面样式布局代码量;再例如NSFetchedResultsController
这样的类和CoreData
heUITableViewController
的完美结合,大大减小相似构架项目的代码量,而且稳定高效。html
这些技巧在objc.io上有一个专门的专题,推荐给你们对应中文站objc中国,感谢objc 中国项目组。ios
若是放在两年前去讨论iOS工程要不要使用Stortboard
进行布局,咱们可能还会犹豫一下,不少iOS程序猿心里会有一种想把一切化为代码掌控在手中的想法,选择拒绝使用Storyboard
或者更早的xib
。但事到现在,iPhone、iPad的屏幕尺寸愈来愈多,工程里为了适配不一样屏幕冗余代码愈来愈长的时候,Storyboard
彷佛成为了咱们必须同时也是苹果公司在引导咱们将要实践的方向。数据库
从iOS 6
中的Autolayout
到iOS 8
中的Size Class
,新技术的涌现正是为了应对更复杂的布局任务。有人可能会反驳说,自动布局也能够用纯代码完成呀。你说的没错,纯代码是能够完成,但其复杂程度远远不是重写Frame这么简单了,更灵活地将Storyboard
和代码结合,才是比较完备的解决方案。xcode
这里经过三个方面介绍经过使用Storyboard
减少工程代码耦合性的途径:网络
IBDesignable
和IBInspectable
Storyboard Preview
NSObject
和Runtime Attributes
IBDesignable
和IBInspectable
的出现为Storyboard
提供了可视化使用高度自定义控件的方法,例子中咱们在制做一个双行标签控件,用来显示日期和星期,命名为DateLabel
,使用方法以下:编辑器
objc//IB_DESIGNABLE 标记 IB_DESIGNABLE @interface DateLabel : UIView //IBInspectable 标记 @property (nonatomic, strong) IBInspectable NSString* dateLabelText; @property (nonatomic, strong) IBInspectable NSString* weekLabelText; @end
其中,IB_DESIGNABLE
标记赋予咱们的继承类DateLabel
能够在界面编辑器里面实时渲染的特权。IBInspectable
则赋予让界面编辑器能够设置或者预置View
的参数dateLabelText
和weekLabelText
。具体很少介绍了,有点跑题,你们能够参见如何在iOS 8中使用Swift和Xcode 6制做精美的UI组件,一样适用于Objective-C
和Swift
。工具
引用上文介
IBInspectable
支持Int
,CGFloat
,Double
,String
,Bool
,CGPoint
,CGSize
,CGRect
,UIColor
,UIImage
等类型的变量。布局
如今在Github
上已经有一部分开源的UI控件使用了这项特性,如此一来,不少须要在代码中实现的控件自定义特性,均可以在Storyboard
中完成,后者的优点也很明显:学习
ViewController
中的定制View
代码,减少耦合Storybord
中提供了预览功能,能够预览其界面在各个尺寸设备上的真实显示效果。详见Xcode 6中学习Swift、CloudKit 和 Testflight,搜索Storyboard Preview
。
你们对这个概念再熟悉不过了,但你们有没有对他做为一个没有界面的控件在Storyboard
做用产生过疑问呢。先来看下这篇文章 0代码ViewController的前言。
Storyboard
中的NSObject
能够是UITableView
的DataSource
,也能够是MapView
的Delegate
,连线一下,就能将本来在ViewController
中写得最多的代理方法所有移出,而且,当你须要的时候,这些现成的代理方法,能够直接移到其余的项目中使用。
Runtime Attributes
功能则能够在Storyboard
中给参数写好初始值,但这里若是控件没有对应的参数的话,则会出现下面的报错。
Failed to set (xxx) user defined inspected property on (xxx): [ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key xxx.
当你了解了Storyboard
的基本原理,就会发现Storyboard
是一个很好用的工具,是Model-View-Controller
模型中Controller
跳转逻辑和View
初始化的实用载体,从根本上把Controller
中的导航代码移出,把页面配置代码、触摸事件甚至协议委托方法分摊到其余实例中,各个类各司其职,整个项目的逻辑也变的更加清晰、更易维护。