當我在Xcode中創建一個新的iOS項目,無論它是iPhone/iPad設備獨占還是universal的,我做的第一件事總是刪除Storyboard。
並且,和你們想象的不同,我並不是想用XIB來代替Storyboard,我完全不使用Interface Builder。
Treehouse論壇對此有很棒的討論,並且我聽到的說法總是類似:Interface Builder會鼓勵做出壞的實踐。
因為我之前有在Window平台使用Visual Studio開發的經驗,我可以很自信的說,Interface Builder非常不好,至少與VS比較是這樣。Visual Studio之所以更優秀,其原因之一在於標記式語言(XAML),它能被設計師使用,就像HTML相對於web一樣。
不管怎麼說,讓我們回到iOS上來。
使用Interface Builder最壞的地方是,它讓分解視圖塊以及從視圖控制器(view controller)使用視圖的工作大大增加了。它的後果是導致出現體積臃腫的視圖控制器,而這是應該避免的,並且它們編輯起來簡直是一個噩夢。
即使你做了這些多出來的工作,並且提取出部分UI到可重用的視圖裡,你在Interface Builder裡看到的將是一個個白色塊,裡面包裹著可重用視圖,但你不能直觀的看到它們。(譯者注:根據網友指出,最新版的Xcode已經能看到了)
另一個問題是outlets,在合並的時候它們可能偶然的斷開連接,或者如果你在重用視圖時忘記連接它們,你的應用會崩潰。
有些人可能會爭論說,當面臨屏幕適配問題時,使用Auto Layout和IB結合是一種好的解決辦法。這一點我仍然不同意——首先我認為在IB中管理布局約束是噩夢,使用拖拽很難將視圖調整到精確的位置,元素會 突然對齊到鄰近的視圖,並且當你添加多個box時,它們的層級順序會打亂並且改變其它box。
與此對應的是,在Github上有不少Auto Layout的擴展(如Masonry、Snappy、PureLayout、Cartography),能幫你節省不少功夫。在將你的子視圖實例化到視圖控制器之後,你僅需要重寫updateConstraints並設置約束條件,即可完成不同尺寸屏幕的適配。比如下面的示例使用了PureLayout庫:
updateConstraints.swift
override func updateConstraints() { super.updateConstraints() self.buildStatusIndicatorView.autoPinEdgesToSuperviewEdgesWithInsets(UIEdgeInsetsZero, excludingEdge: ALEdge.Trailing) self.buildStatusIndicatorView.autoSetDimension(ALDimension.Width, toSize: 10) self.buildNumberLabel.autoPinEdgesToSuperviewEdgesWithInsets(UIEdgeInsets(top: 5, left: 15, bottom: 5, right: 5), excludingEdge: ALEdge.Bottom) self.buildNumberLabel.autoSetDimension(ALDimension.Height, toSize: 23) self.branchLabel.autoPinEdge(ALEdge.Top, toEdge: ALEdge.Top, ofView: self.contentView, withOffset: 10) self.branchLabel.autoPinEdge(ALEdge.Trailing, toEdge: ALEdge.Trailing, ofView: self.contentView, withOffset: -10) self.commitMessageLabel.autoPinEdge(ALEdge.Top, toEdge: ALEdge.Bottom, ofView: self.buildNumberLabel, withOffset: 10) self.commitMessageLabel.autoPinEdgeToSuperviewEdge(ALEdge.Leading, withInset: 15) self.commitMessageLabel.autoPinEdgeToSuperviewEdge(ALEdge.Bottom, withInset: 5) self.commitMessageLabel.autoConstrainAttribute(ALAttribute.Width, toAttribute: ALAttribute.Width, ofView: self.contentView, withOffset: -20) }
對於表格視圖需要計算每個單元格的高度,以達到根據Auto Layout約束條件自動調整大小,代碼可以很直觀的完成這一點。特別是當iOS 8引入了UITableViewAutomaticDimension 選項之後。
(本文為CocoaChina翻譯,轉載請注明出處)