天天看點

UI界面:手寫UI代碼或者使用xib和StoryBoard制作UI界面的差別和分析 UI: Code vs Xibs vs StoryBoard

UI界面:手寫UI代碼或者使用xib和StoryBoard制作UI界面的差別和分析 UI: Code vs Xibs vs StoryBoard

UI: Code vs Xibs vs StoryBoard

       最近接觸了幾個剛入門的iOS學習者,他們之中存在一個普遍和困惑和疑問,就是應該如何制作UI界面。iOS應用是非常重視使用者體驗的,可以說絕大多數的應用成功與否與互動設計以及UI是否漂亮易用有着非常大的關系。而随着iOS開發發展至今,可以說在UI制作上大家逐漸分化為了三種主要流派:使用代碼手寫UI及布局;使用單個xib檔案組織viewController或者view;使用StoryBoard來通過單個或很少的幾個(關于這點稍後會進行展開)檔案建構全部UI。應該使用哪種方式來制作UI已經是iOS開發中亘古不變的争論話題了,或許永遠不會有一個統一的結論。但是首先需要知道的是三種方式各有優劣,是以也各有自己最适用的場合,而不會有完全的孰優孰劣。對于初學iOS開發來說,一時間其實是很難判定最适合自己的UI架構方式的。在這篇文章裡我希望能夠通過自己的經驗給出一些意見,以期能幫助入門者來挑選最适合自己應用場景的方案。對于老鳥的話,也不妨對照自己平日的使用習慣和運用場景,看看有沒有可以改進或變化的地方。  

代碼手寫UI

這種方法經常被學院派的極客或者依賴多人合作的大型項目大規模使用。Geek們喜歡用代碼建構UI,是因為代碼是鍵盤敲出來的,這樣可以做到不開IB,手不離開鍵盤就完成工作,可以專注于編碼環境,看起來很cool很高效,而且不到運作時大家都不知道會是什麼樣子,也顯出了程式員這一職業的高大上及神秘氣息(這個真的不是在黑..想想大家一起在設計師背後指點江山的場景吧)。大型多人合作項目使用代碼建構UI,主要是看中純代碼在版本管理時的優勢,檢查追蹤改動以及進行代碼合并相對容易一些。   另外,代碼UI可以說具有最好的代碼重用性。如果你的目的是寫一些可以高度重用的控件提供給其他開發者使用,那毫無疑問最好的選擇應該是使用代碼來完成UIView的子類。這樣進一步的修改和其他開發者在使用時,都會友善不少。使用代碼也是最為強大的,會有xib或者StoryBoard做不了的事情,但是使用代碼最終一定能夠完成所要的需求。   但是代碼手寫UI的劣勢同時也是最明顯的,主要就是一個字:慢。首先相比可視化的IB來說,完成一個并不太複雜的界面,你可能需要寫上數百行的UI代碼。不論是初始化一個Label,還是設定一個frame或者添加一個target-action,都需要寫代碼,這不僅在前期極為浪費時間,在之後維護時代碼定位和尋找也會很痛苦。其次,因為你無法直覺地看到你能得到的結果,是以你很可能需要不斷地Cmd+R/Cmd+.來修改各個視圖的位置大小。即使你用上了Reveal或者RestartLessOften之類的工具,也還是無法特别友善地完成需要的布局。另外加上如果需要利用AutoLayout來進行尺寸适配的話,使用代碼進行限制就更加頭疼了。很多時候一個無法滿足的限制的問題就夠來回運作修改調試很長時間了。  

Xibs

相對于代碼,使用IB和xib檔案來組織UI,可以省下大量代碼和時間,進而得到更快的開發速度。如果你曾經受到過微軟家Visual Basic或者其他Visual系的可視化界面的荼毒與殘害,是以懷疑Interface Builder的純正血統和工作能力,建議可以看看這些資料以糾正三觀: Jean-Marie Hullot的Interface Builder神話, 西裝革履的青澀喬幫主在NeXT時親手用IB建構應用(需要翻牆)。另外,不妨打開你的Mac上的Application檔案夾中或者iPhone上Apple家的各種應用。你會驚奇地發現,IB遠比你看到的要強大:小至電腦取色器這類小工具,大至iWork三件套,Aperture或Final Cut這樣的專業級應用,無一不是使用IB來完成UI制作的。   其實IB和xib是從iOS SDK初次面世開始就是捆綁在開發者工具套裝内的内容了,而到了Xcode 4之後更被直接內建到了Xcode中成為了IDE的一部分。xib設計的一大目的其實是為了良好的MVC:一般來說,單個的xib檔案對應一個ViewController,而對于一些自定義的view,往往也會使用單個xib并從main bundle進行加載的方式來載入。IB幫助完成view的建立,布局和與file owner的關系映射等一些列工作。對于初學者來說,牢記xib的檔案都是view的内容,有助于建立起較好的MVC的概念,進而在開發中避免或少走彎路。   xib檔案之前一大被诟病的問題是檔案内容過于複雜,可讀性很差,即使隻是簡單打開沒有編輯也有可能造成變化而導緻合并和送出的苦難。在Xcode 5中Apple大幅簡化了xib檔案的格式,使其變得易讀易維護。可以說現在對于xib檔案在版本管理上其實和純代碼已經沒有太大差異,隻要仔細看過一遍xib的檔案内容,自然能了解絕大部分,并很好地追蹤并查找過往的修改記錄了。   當然xib也不是完美的。最大的問題在于xib中的設定往往并非最終設定,在代碼中你将有機會覆寫你在xib檔案中進行的UI設計。在不同的地方對同一個屬性進行設定,這在之後的維護中将會是噩夢般的存在。因為其實IB還是有所局限的,它沒有邏輯判斷,也很難在運作時進行配置,而反之使用代碼确是無所不能的。在使用xib時,輔以部分代碼來補充和完成功能幾乎是不可避免的。關于這點在開發時應該予以高度重視,如果選擇xib,那麼要盡量将xib的工作和代碼的工作隔離開來:能夠使用xib完成的内容就統一使用xib來做,而不要說三個Label其中兩個在xib設定了字型而另一個卻在代碼中完成。盡量僅保持必要的、較少的IBOutlet和IBAction會是一個好方法。  

StoryBoard

iOS5之後Apple提供了一種全新的方式來制作UI,那就是StoryBoard。簡單了解來說,可以把StoryBoard看做是一組viewController對應的xib,以及它們之間的轉換方式的集合。在StoryBoard中不僅可以看到每個ViewController的布局樣式,也可以明确地知道各個ViewController之間的轉換關系。相對于單個的xib,其代碼需求更少,也由于集合了各個xib,使得對于界面的了解和修改的速度也得到了更大提升。減少代碼量就是減少bug量,這也是程式開發中的真理之一。   在Xcode5之後,StoryBoard已經成為建立項目的預設配置,這也代表了Apple對開發者的建議和未來的方向。WWDC2013的各個Sample Code中也基本都使用了StoryBoard來進行示範。可以預見到,之後Apple必定會在這方面進行繼續強化,而反之純代碼或者單個xib的方式很可能不會再得到增強。   如果不考慮iOS版本的支援(其實說實話現在已經很少還見到要從iOS4開始支援的app了吧),現在StoryBoard面臨的最大問題就是多人協作。因為所有的UI都定義在一個檔案中,是以很多開發者個人或企業的技術負責人認為StoryBoard是無法進行協作開發的,其實這更多的是一種對StoryBoard的陌生所造成的誤解。雖然Apple并沒有在WWDC明确提及,但是沒有人規定整個項目隻能有一個StoryBoard檔案。一種可行的做法是将項目的不同部分分解成若幹個StoryBoard,并安排開發人員對自己的部分進行負責。簡單舉例比如一個有4個tab功能互相獨立的基于UITabBarViewController的應用,完全可以使用4個StoryBoard來分别代表4個tab,并在互相無幹擾的情況下完成開發。這樣一來就不會存在所謂的沖突問題了。StoryBoard的API是如此簡單,現在的SDK中一共方法數量一隻手就能數過來,是以具體方法在這裡就不再羅嗦了。   StoryBoard的另外的挑戰來源于ViewController的重用和自定義的view的處理。對于前者,在正确封裝接口以及良好設計的基礎上,其實StoryBoard的VC重用與代碼的VC重用是沒有本質差別的,在StoryBoard中添加封裝良好需要重用的Scene即可解決。而對于後者,因為StoryBoard中已經不允許有單個view的存在,是以很多時候我們還是需要借助于單個的xib來自定義UI。這一點可以說是由于StoryBoard的設計思路所造成的,StoryBoard更強調的是一種層次結構,是在全局的視角上來組織UI設計和遷移。而對于單個的view,更多的會注重于重用和定制,而與整個項目的流程沒有太大關系。相信抓住這一要點,就能很好地了解什麼時候使用xib,什麼時候使用StoryBoard。   關于StoryBoard最後要說的是,現在會有一些對于StoryBoard性能上的擔憂。因為相對于單個xib來說,StoryBoard檔案往往更大,加載速度也相應變慢。但是其實随着現在裝置的更新換代,在iPhone4都難覓的今天,這點性能上的差距幾乎可以忽略了。而再之後的裝置,不論讀取還是解析,隻會越來越快。是以性能上的問題完全是沒有擔心的必要的。  

我的觀點和選擇

我入門的時候是使用xib的,因為那時候還沒有StoryBoard,而我也不是喜歡代碼的學院派Geek。到現在,三種方式我都有嘗試過,并分别得到了一些可能還并不是特别深刻體會。對于現在的我來說,xib是我的奶酪,也是我在自己的一些項目裡一直使用的方式,我可以在極短短時間内用xib架起一套包括自定義要素和良好部件重用性複雜UI。但是在我嘗試了幾次使用StoryBoard制作demo之後,我已經決定在之後的項目轉向使用StoryBoard。一方面因為确實是未來方向(每次新工程删StoryBoard很讨厭..),現在的StoryBoard專有的preview功能,以及之後AutoLayout的進一步改進等都很值得期待;另一方面也覺得奶酪放一個地方太久了會不好,趁着iOS7的大變革,也更新一下自己的觀念和方式,把奶酪換個地方擺擺,也許會對以後大有裨益。   對于初學者來說,我并不建議上手就直接使用代碼來進行UI制作和布局,因為冗長的UI代碼确實非常乏味無趣。盡快看到成品,至少盡快看到原型,是保持興趣,繼續深入和從事職業的有效動力。是以如果有可能有條件,在老鳥的指導下選擇StoryBoard來進行快速建構(或者如果是單個人開發的話,可以不用考慮多個StoryBoard協作,就更容易),會是入門的好選擇。而最新的教程和文檔已經開始逐漸偏向StoryBoard,關于StoryBoard的問題在SO上關注度也會更高,這樣在入門時會有更多的資料可以進行參考。   這并不是說不需要關心代碼UI或者xib,因為使用StoryBoard的時候在隻能使用代碼以及自定義單個view時,還是不可避免地需要接觸它們的。這裡想給的一點建議就是,雖然你不依賴代碼來進行UI制作,但是了解并掌握如何使用純代碼來從頭建構UI還是非常必要的:包括從建立Window開始,到初始化ViewController,添加必要的view,設定它們的property,以及添加和處理它們的各種響應及responser鍊等内容。現在iOS開發入門非常容易,Xcode和xib/StoryBoard幫助開發者隐藏了太多的細節,但是很多時候如果你不明白underhood到底是些什麼,為什麼這些xib/StoryBoard會這樣運作的話,經常會出現卡在一些很可笑的和初級的bug上找不着北,這其實會是對時間的巨大浪費,很不值得。