綜述
凡是維護過中型項目的iOS工程師都應該有過類似的體驗:ViewController
代碼繁重、功能復雜、維護困難,整個工程寥寥幾個ViewController
就完成了整個項目的開發。每個控制器中都囊括了所有的頁面布局、委托代理、網絡請求、數據庫操作和核心功能,這樣的代碼往往問題重重,修改起來牽一發而動全身,著實令人頭疼。
為了應對這一系列的問題,蘋果公司的工程師給我們提供了很多選擇去更好的在項目工程中貫徹MVC
的設計理念,例如使用從前的Interface Builder
制作xib
可視布局,現在已經內置到xcode
里面,并且提供了更為強大Storyboard
功能,來減少控制器
中的頁面樣式布局代碼量;再例如NSFetchedResultsController
這樣的類和CoreData
heUITableViewController
的完美結合,大大減少類似構架項目的代碼量,并且穩定高效。
這些技巧在objc.io上有一個專門的專題,推薦給大家對應中文站objc中國,感謝objc 中國項目組。
Storyboard與代碼耦合性
如果放在兩年前去討論iOS工程要不要使用Stortboard
進行布局,我們可能還會猶豫一下,很多iOS程序猿內心會有一種想把一切化為代碼掌控在手中的想法,選擇拒絕使用Storyboard
或者更早的xib
。但事到如今,iPhone、iPad的屏幕尺寸越來越多,工程里為了適配不同屏幕冗余代碼越來越長的時候,Storyboard
似乎成為了我們必須同時也是蘋果公司在引導我們將要實踐的方向。
從iOS 6
中的Autolayout
到iOS 8
中的Size Class
,新技術的涌現正是為了應對更復雜的布局任務。有人可能會反駁說,自動布局也可以用純代碼完成呀。你說的沒錯,純代碼是可以完成,但其復雜程度遠遠不是重寫Frame這么簡單了,更靈活地將Storyboard
和代碼結合,才是比較完備的解決方案。
這里通過三個方面介紹通過使用Storyboard
減小工程代碼耦合性的途徑:
-
IBDesignable
和IBInspectable
- 預覽
Storyboard Preview
-
NSObject
和Runtime Attributes
IBDesignable和IBInspectable
IBDesignable
和IBInspectable
的出現為Storyboard
提供了可視化使用高度自定義控件的方法,例子中我們在制作一個雙行標簽控件,用來顯示日期和星期,命名為DateLabel
,使用方法如下:
//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
代碼,減小耦合
預覽Storyboard Preview
Storybord
中提供了預覽功能,可以預覽其界面在各個尺寸設備上的真實顯示效果。詳見Xcode 6中學習Swift、CloudKit 和 Testflight,搜索Storyboard Preview
。
NSObject和Runtime Attributes
大家對這個概念再熟悉不過了,但大家有沒有對他作為一個沒有界面的控件在Storyboard
作用產生過疑問呢。先來看下這篇文章 0代碼ViewController的前言。
Storyboard
中的NSObject
可以是UITableView
的DataSource
,也可以是MapView
的Delegate
,連線一下,就能將原本在ViewController
中寫得最多的代理方法全部移出,并且,當你需要的時候,這些現成的代理方法,可以直接移到其他的項目中使用。
Runtime Attributes
功能則可以在Storyboard
中給參數寫好初始值,但這里如果控件沒有對應的參數的話,則會出現下面的報錯。
Failed to set (xxx) user defined inspected property on (xxx): [<xxx 0xXXXXXXXX> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key xxx.
Storyboard小結
當你了解了Storyboard
的基本原理,就會發現Storyboard
是一個很好用的工具,是Model-View-Controller
模型中Controller
跳轉邏輯和View
初始化的實用載體,從根本上把Controller
中的導航代碼移出,把頁面配置代碼、觸摸事件甚至協議委托方法分攤到其他實例中,各個類各司其職,整個項目的邏輯也變的更加清晰、更易維護。
轉載請注明出處