Storyboard的愛與恨
儘管現在已經是Apple將Storyboard整合進Xcode中的第四個年頭,大家對於Storyboard的評價仍然褒貶不一。有早期就選擇轉向Storyboard用於UI開發的國內業界領頭人物,也有建立專案就立馬刪除Storyboard的大牛。我經歷過純程式碼佈局,同時也在多個多人合作專案中使用Storyboard開發介面。在初期繞過各種坑後,Storyboard將會是快速構建UI介面的好幫手,特別是在現如今裝置解析度與尺寸日益增加的情況下,它可以幫助工程師們節約大量的介面程式碼書寫時間。Storyboard存在的一大意義在於為UI提供了視覺化開發方式,另一方面提供了一種更好的MVC的View層實現方式,讓你的ViewController程式碼更簡潔。當然,Storyboard的不足仍然不可忽視,錯誤的難以定位經常讓剛上手的開發者們手足無措,相比於程式碼更不容易閱讀的XML原始檔所導致多人合作中的衝突不易解決等問題仍然有待完善。本文從各個方面介紹一下Storyboard,分享一下Storyboard的一些使用心得。
歷史
1986年Jean-Marie Hullot發明了IB(Interface Build--Storyboard的前身),並且和Macintosh的工具箱無縫融合,這一工具被Denison Bollay發現了。第二年, Denison Bollay帶著Hullot和他的IB到NeXT,將IB演示給Steve Jobs看。老喬立意識到了IB的價值,並將其納入到了NeXTSTEP中。之後Steve 帶著NeXT的技術結晶(當然也包括IB)重新迴歸Apple,並將之整合到了Apple的體系中。2008年第一代iPhone SDK釋出的時候,IB就已經捆綁在其中。到了Xcode4,Apple更是直接將其整合進IDE裡。隨後隨著不斷地改進,更新,演變,最終變成了我們今天所看到的Storyboard。從某種角度來說,Storyboard也是老喬留給我們的眾多禮物之一。
故事板能做什麼
故事板主要為我們提供了以下的功能:(這些功能都是視覺化的)
-
Auto Layout
-
Size Classes
-
Secnce的跳轉
-
程式碼視覺化
Auto Layout
自動佈局顛覆了之前直接操作Frame的佈局方式,從思考View應該在哪個位置,變成了考慮在特定條件下,View的所處的位置需要滿足哪些條件。通過這些條件來確定View的Frame。自動佈局在實際應用中大體上可以將分為三組:
View與Super View的約束
View自身的約束
View與Other View的約束
假如我們需要在程式碼中使用自動佈局可以使用 Visual Format Language或者NSLayoutConstraint的簡單工廠方法來生成約束,然後新增到View上。我們來看一個例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
//用程式碼來實現上圖中View與Super View的約束
UIView *superView = self.view;
UIView *subView = [[UIView alloc] init];
NSLayoutConstraint *leadingConstraint = [NSLayoutConstraint constraintWithItem:superView
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:subView
attribute:NSLayoutAttributeLeading
multiplier:1
constant:15];
NSLayoutConstraint *TrailingConstraint = [NSLayoutConstraint constraintWithItem:superView
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:subView
attribute:NSLayoutAttributeTrailing
multiplier:1
constant:15];
//topConstraint init...
//bottomConstraint init...
[superView addConstraint:leadingConstraint];
[superView addConstraint:TrailingConstraint];
[superView addConstraint:topConstraint];
[superView addConstraint:bottomConstraint];
// 如果是iOS8+ 則使用下面的方式來啟用Constraint
// leadingConstraint.active = YES;
// leadingConstraint.active = YES;
// leadingConstraint.active = YES;
// leadingConstraint.active = YES;
|
是不是一大團亂糟糟的程式碼?Visual Format Language用起來更加令人崩潰。好在業界已經有比較好的程式碼自動佈局的第三方解決方案。但是仍然會有大堆的簡單介面佈局程式碼殘留在你的程式碼中。
為了讓你的生活更輕鬆(也為了讓程式碼更清爽),Storyboard就包含了非常優雅的視覺化自動佈局解決方案。以上一切,在Storyboard中都被濃縮成了兩個按鈕(下圖紅圈中的橢圓按鈕)。
-
紅框1:為被選中View和離他最近的View(可能是SuperView,也可能是另一個同層級的View,看哪個離它更近)新增Leading、Training、Top、Bottom四個屬性約束。
-
紅框2:為View新增自身寬和高約束
-
紅色橢圓左側按鈕:當選中多個View時,為多個View新增約束
只需要點選幾下滑鼠,Storyboard就可以幫你輕鬆完成檢視佈局。
Auto Layout Debug
使用程式碼來對Auto Layout佈局的另一個缺點在於debug的困難。當添加了多餘的約束,往往只能在執行時才能發現錯誤。同時,要尋找出是哪一行程式碼添加了錯誤的約束也比較費力(往往連控制檯都沒有錯誤輸出)。
而Storyboard卻為此提供了非常友好的靜態檢查。主要針對View的約束、佈局提供警告和Error,甚至是解決方案。
上圖的例子是:我們為Label添加了多餘的約束,Storyboard用紅色標記出衝突的約束,並給出修改建議:刪除其中一個約束以保證約束的正確性。是不是很友好? :)
Size Classes
Apple 與iOS 8推出了Size Classes的概念。意在解決因裝置尺寸造成的適配問題。Size Classes通過將介面的寬度和高度抽象為正常和緊湊兩種概念,通過合理的組合,可以將現有裝置(以及未來將要出現的裝置)劃分到不同的Size中。因此,無論是程式碼還是介面佈局,只需要針對Size進行,而不用再拘泥於分辨是iPhone還是iPad,是橫屏還是豎屏的問題了。Size Classes的推出是具有前瞻性的,無論是Apple Watch還是iOS 9推出的的iPad 分屏模式,都可以用Size Classes完美解決適配的問題。
Size Classes和現有裝置的對照表如下:
在之前,我們要對橫屏豎屏的介面進行區分,程式碼一般是這