[CS193P] 第五堂課摘要及心得筆記

開課至今已經過了一個多月了,在第五堂課之前的內容大多都是一些基礎的觀念,是用來幫助我們建立iPhone應用程式的基本概念。而在這堂課開始,我們將深入了關於iPhone應用程式的深入細節。而在第五堂課中,主要的內容就是關於View的部份,也就是介面的呈現。
評論
評論

開課至今已經過了一個多月了,在第五堂課之前的內容大多都是一些基礎的觀念,是用來幫助我們建立 iPhone 應用程式的基本概念。而在這堂課開始,我們將深入了關於 iPhone 應用程式的深入細節。而在第五堂課中,主要的內容就是關於 View 的部份,也就是介面的呈現。

Views

在前面幾堂課中我們曾經提過 MVC 的概念,也大概解說了 View 主要負責功能:顯示內容、處理事件。而在實做上,每個 View 都是 UIResponder 的子類別,在畫面上以方形呈現。此外,每個 View 下面都可以包含其他的 View,形成一個階層的形式,要注意的是,每個 View 中涵蓋的子 View 是用陣列存放,根據 Index 不同會決定顯示的優先順序。

而在 iPhone 程式中,每個程式裡面會有唯一一個 UIWindow 這個 View,而剩下的所有的 View 都會包含在 UIWindow 中。我們要如何新增一個 View 到程式裡面呢?有兩種作法,一種是透過 Interface Builder 新增,另外也可以透過 UIView 的一些相關方法:

 - (void)addSubview:(UIView *)view;  - (void)removeFromSuperview;

透過 - (void)addSubview 方法新增的 view 會自動被 retain,需要注意的是,當要移除某個 View 的時候直接對那個 View 呼叫 - (void)removeFromSuperview 即可。當然,UIView 也提供了一些方法讓我們可以手動調整 View 的優先順序:

 - (void)insertSubview:(UIView *)view atIndex:(int)index;  - (void)insertSubview:(UIView *)view belowSubview:(UIView *)view;  - (void)insertSubview:(UIView *)view aboveSubview:(UIView *)view;  - (void)exchangeSubviewAtIndex:(int)index withSubviewAtIndex:(int)otherIndex;

如果當我們只是想要暫時隱藏某個 View 的顯示,我們可以直接透過 theView.hidden = YES; 就可以把 View 藏起來,不需要將 View 移除掉。

UIView 的定位系統

UIView 掌管了畫面上元素的顯示,自然會需要精準的計算,與座標系統有關的物件結構有以下幾個:

  • CGPoint -- 座標上的點,包含 x 和 y
  • CGSize -- 物件的大小,包含 width 和 height
  • CGRect -- 結合以上兩者,包含 origin 和 size

相對應的建立函式有以下幾種,其中的參數均為浮點數:

  • CGPointMake(x, y)
  • CGSizeMake(width, height)
  • CGRectMake(x, y, width, height)

在 iPhone 的畫面上,最左上角的為原點,x 軸將往右延伸而 y 軸則是往下,如下圖所視:

View 的座標和大小又可以有兩種表達方式 :Frame 和 Bounds。Frame 就是以上層 View 的角度來看的座標系統,而 Bounds 則是自己本身的座標系統
,而對最上層的 View 來說,其 Frame 等同於 Bounds。需要注意的是,Frame 並沒有被儲存在物件中,是透過物件的中心點座標以及長寬的資訊被計算出來的。對於 Bounds 和 Frame 有疑惑的朋友,可以參考下圖:

你或許會感到好奇,這樣看起來 Frame 跟 Bonuds 的功能大同小異,但是當物件若進行旋轉,則 Frame 會變成上層 View 中能涵蓋此 View 的最小的四邊形,如下圖所示:

那我們要在什麼時候使用 Frame,而又在什麼時候使用 Bounds 呢?可以用以下方法區隔:

  • 當你在使用 View 的時候,透過 Frame 去操作,像是當我們建立 View 的時候或是將 View 加入另一個 View 時
  • 當你在實做 View 的時候,透過 Bounds 去操作,例如處理事件或是畫 View 的元素時

建立 View

要如何建立 View 的物件呢?其實相當的簡單。我們只要在 Interface Builder 中將想要的 UI 物件拉到 Nib 檔中就可以了,就像作業 2B 一樣的操作。

不過我們也可以用程式碼來建立新的 View,透過 UIView 物件的 ;- (id) initWithFrame: (CGRect) frame 就可以依照 Frame 建立新的 View。但千萬要記得,剛建立出來的 View 要透過 addSubview 將它加入到正確的 View 當中。

那我們要如何建立自己的 View 類別呢?其實我們只要創立一個 UIView 的子類別這樣就可以了!

UI 動畫

UIView 中提供了許多可以作成動畫效果的相關 property,像是 frame、bounds 或是 alpha 和 transform 都是常見的例子。而除了這些可以作成動畫的元素之外,也有一些相關的選項。下面是一個簡單的範例:

- (void)showAdvancedOptions {     // 假設 polygonView 和 optionView 的存在     [UIView beginAnimations:@”advancedAnimations” context:nil]; // 開始動畫     [UIView setAnimationDuration:0.3]; // 動畫時間設定為 0.3      optionsView.alpha = 1.0; // 將 optionView 的 alpha 值設到 1(也就是完全顯示的狀況,目前為 0,也就是隱藏)      CGRect polygonFrame = polygonView.frame;  // 取得 polygonView 的 frame     polygonFrame.origin.y += 200;  // 移動 frame     polygonView.frame = polygonFrame; // 將移動過後的 frame 指派給 polygonView,也就是讓 polygonView 往下移動     [UIView commitAnimations]; // 執行動畫 }

在以上這個範例中,我們將可以看到當此方法被呼叫之後,polygonView 將會往下移動,而 optionView 則從原本的透明狀態恢復成正常顯示,就如同下圖中的顯示:

然而,iPhone 上的動畫是非同步的,誠如上面程式所見,我們其實不知道什麼時候動畫執行完畢。為了解決這個問題,我們可以使用 [UIView setAnimationDelegate:myController]; 來設定 delegate 類別,當動畫要開始或結束時都會分別呼叫 delgate 類別的對應方法。詳細的方法介紹在投影片的第 73 頁可以參考。

以技術上的角度來講,雖然 iPhone 是透過硬體加速來完成這些絢麗的動畫,但實際是每一張 View 的繪圖結果是會被快取起來的,只有當內容有做改變的時候 -drawRect 才會被再度呼叫。

最後,除了以上的物件移動及透明度的修改之外,UIView 也有提供變形的 property,也就是 transform。透過這個 property 和 Core Graphic 的函式,我們可以設定像是縮放、旋轉等複雜的變形效果。有興趣的朋友還請參考下面的參考資源。

結論

在這次的內容中我們學到了關於 View 的概念以及如何使用 View 來建立一些動畫的效果,而在下一次的筆記中,我們將前進到第六堂課,還請各位讀者敬請期待!

參考資源



精選熱門好工作

軟體測試工程師 (SQA Engineer)

FunNow
臺北市.台灣

獎勵 NT$15,000

Android 工程師

FunNow
臺北市.台灣

獎勵 NT$15,000

Backend Engineer (Goodnight App)

新加坡商拍拖有限公司台灣分公司
臺北市.台灣

獎勵 NT$15,000