UIView及UIViewController的使用Best Practice初探(1)

在開發iOS App的過程中,目前我最常處理的原生Class就是UIView以及UIViewController了。這2個Class可說是iOS開發中,非常重要的Class之一,所有UI元件的產生,或是為了刻出設計師所畫出的精美的圖,有很大的機會需要用到UIView。

過去在建立UIView或是UIViewController時,總是用網路上搜尋到的資料,比如說如果要在UIViewController裡面建立UIView,過去的做法是把UIView init的function全部把它們塞在viewDidLoad區塊之中,讓整段建立的code非常長。但自從重新開始閱讀Apple提供有關UIView以及UIViewController的文件之後,開始對於適當得使用UIView以及UIView的原生功能有了新的認識。

一般來說,常見的UIView建立方式如下:

UIView *view = [[UIView alloc] init]
view.backgroundColor = [UIColor yellowColor]
view.frame = CGRectMake(0, 0, 100, 100)];
[self.view addSubView:view]

上述是最基本的方式,但如果你想要幫UIView加入許多客製化的特徵能比如顏色,變換位置,其他客製化等等,結果就是code的長度會非常長,有時還會看到為了不同的目的,結果加了許多自訂的Function。因此,是否有能夠加強可讀性,並讓code都處在最佳位置呢?

仔細去看UIViewController的官方說明文件,其實Apple已經有提供許多Callback function讓你可以在對的時間點建立裡頭的元件了,當然也包含UIView。

其中在UIViewController中,值得一提的Callback function如下:

-(void)loadView

- (void)viewDidLoad

- (void)viewWillLayoutSubviews

可以從文件中看出,這三個Function的時間點剛好是從上而下照順序進行的。UIViewController會在loadView的時間點開始建立畫面裡頭所以需的instance,而當建立完成之後則會呼叫viewDidLoad。最後則會呼叫viewWillLayoutSubviews來實際”排版(Layout)”整個UIViewController的畫面。

看到這邊,應該可以想像出當初在設計的Apple工程師,已經幫我們把要刻畫整個畫面的流程想好了,也就是說,當loadView的時間,Apple希望我們在這裡跟著UIViewController的生命週期,在這個階段建立裡頭所需的instance,包含UIView或是其他的元件。然後,在viewDidLoad時,加入當完成instance init之後所想要該instance做的事,最後,則在viewWillLayoutSubviews才去畫出該instance的位置!

直接來看實際的例子,我們把上面的code分開來放看看:

- (void)loadView
{
[super loadView]

UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
[self.view addSubView:view]
}
- (void)viewDidLoad
{
[super viewDidLoad];
    view.backgroundColor = [UIColor yellowColor]
}
- (void)viewWillLayoutSubviews
{
view.frame = CGRectMake(0, 0, 100, 100)];
}

如何?以上就是符合該邏輯所實作的方法,目前的code還很簡單,所以可能看不出把UIView建立的code分開放的必要。但是要記住的是,UIViewController往往都不是只有一個UIView而已,可能會有數十個UIView instance在其中,因此,這樣區分有開始有意義了,當你想要改變某個UIView的位置,就去viewWillLayoutSubviews去找,而不用在茫茫的code海中,去找到對的function去改。並且對整體的設計也較有邏輯,維護性以及可遵從性也較高。