1. 程式人生 > >Storyboard的愛與恨

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的約束

QQ截圖20160224113505.png

View自身的約束

QQ截圖20160224113548.png

View與Other View的約束

QQ截圖20160224113613.png

假如我們需要在程式碼中使用自動佈局可以使用 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中都被濃縮成了兩個按鈕(下圖紅圈中的橢圓按鈕)。

1111.png

  • 紅框1:為被選中View和離他最近的View(可能是SuperView,也可能是另一個同層級的View,看哪個離它更近)新增Leading、Training、Top、Bottom四個屬性約束。

  • 紅框2:為View新增自身寬和高約束

  • 紅色橢圓左側按鈕:當選中多個View時,為多個View新增約束

只需要點選幾下滑鼠,Storyboard就可以幫你輕鬆完成檢視佈局。

Auto Layout Debug

使用程式碼來對Auto Layout佈局的另一個缺點在於debug的困難。當添加了多餘的約束,往往只能在執行時才能發現錯誤。同時,要尋找出是哪一行程式碼添加了錯誤的約束也比較費力(往往連控制檯都沒有錯誤輸出)。

而Storyboard卻為此提供了非常友好的靜態檢查。主要針對View的約束、佈局提供警告和Error,甚至是解決方案。

-----2016-02-19-16-30-51.png

上圖的例子是:我們為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和現有裝置的對照表如下:

QQ截圖20160224114047.png

在之前,我們要對橫屏豎屏的介面進行區分,程式碼一般是這