第 6 章
使用堆疊視圖設計UI

To the user, the interface is the product.

- Aza Raskin

我已經針對自動佈局(Auto Layout )進行了簡短的介紹,其中所示範的案例很簡單。不過,當你的 App UI 變得更複雜後,你會發現要定義所有 UI 物件的約束條件會更加困難了。從 iOS 9 開始,Apple 導入了堆疊視圖(Stack View )的強大功能,讓開發者的開發工作能更輕鬆些。你不再需要幫所有的UI 物件定義自動佈局約束條件,堆疊視圖會負責大部分的工作。

在本章中,我們將繼續介紹在介面建構器上的 UI 設計。我會介紹如何建立更完整、可在真實世界運用到的UI。你將會學習到:

  1. 使用堆疊視圖來佈局使用者介面。
  2. 使用圖片視圖(Image View)來呈現圖片。
  3. 使用內建的素材目錄來管理圖片。
  4. 使用尺寸類別來採用堆疊視圖。

除了以上的內容之外,我們將探索更多有關自動佈局的內容。你將會很驚訝不需要撰寫任何一行程式碼的情況下,就能完成這麼多的工作。

何謂堆疊視圖

首先最重要的是,何謂堆疊視圖?堆疊視圖提供一個簡化的介面,以行或列來佈局視圖的集合。在 Keynote 或是微軟的 Powerpoint,你可以將多個物件群組起來,讓它們可以使用一個單一物件來移動或調整大小。堆疊視圖提供了一個非常相似的功能,你可以嵌入多個 UI 物件進入堆疊視圖。大多數的情況下,所有嵌入一個堆疊視圖內的視圖,你不需要定義自動佈局約束條件。

Quick note: 對於嵌入堆疊視圖內的視圖,一般稱作「排列視圖」( Arranged View )。

這個堆疊視圖會管理它的子視圖(subview)的佈局,並且自動幫你採用佈局約束條件。這表示子視圖準備適應各種不同的螢幕尺寸。甚至,你可以嵌入一個堆疊視圖至另一個堆疊視圖內,來建立更複雜的使用者介面。聽起來很酷,對吧?

但是不要誤解我的意思,這並不表示你不需要處理自動佈局的工作。你仍然需要定義堆疊視圖的佈局約束條件。它只是幫你省下針對每個 UI 元件定義約束條件的時間,並且讓它能夠更加容易地從佈局中新增或移除視圖。

圖 6.1. 水平堆疊視圖(左圖)/垂直堆疊視圖(右圖)
圖 6.1. 水平堆疊視圖(左圖)/垂直堆疊視圖(右圖)

Xcode 提供兩種使用堆疊視圖的方式,如圖 6.1 所示。

  1. 你可以從元件庫(Object Library)中拖曳一個水平堆疊視圖/垂直堆疊視圖,然後置放於 Storyboard 中。你可拖曳、置放標籤、按鈕、圖片視圖等視圖物件至堆疊視圖中。
  2. 另外,你也可以在自動佈局列中使用「Stack」選項。針對這個方式,你只要選取兩個或者多個視圖物件,然後選取「Stack」選項,介面建構器(Interface Builder )會嵌入物件至堆疊視圖,並重新自動調整大小。

假使你對如何使用堆疊視圖仍是沒有概念的話,請不用擔心,我們會在本章針對這兩種方式做介紹。只要繼續往下閱讀,你很快便會明白我的意思。

以範例App示範

我們來看一下所準備建立的範例 App。我會示範如何使用堆疊視圖來佈局歡迎畫面,如圖 6.2 所示。

圖 6.2. 範例App
圖 6.2. 範例App

你可以不使用堆疊視圖而建立出相同的 UI,但是你會發現堆疊視圖完全改變你佈局使用者介面的方式。同樣的,本章不需要寫程式碼,我們將重點放在使用介面建構器,來建立一個自適應的使用者介面。這是 App 開發的一個很關鍵的技巧。

建立新專案

現在開啟 Xcode,並建立一個新的 Xcode 專案。選取「Application( 在iOS 下面) → App」,並點選「Next」按鈕。在專案選項中,你可以填入下列資訊:

  • Product Name(專案名稱): StackViewDemo – 這是你的App名稱。
  • Team: 這裡先不做更動。
  • Organization Identifier(組織識別碼): com.appcoda – 這其實是網域名稱的倒寫, 如果你自己有網域,你可以使用你自己的網域名稱。否則的話,你可以使用「com. appcoda」或者只要填入「edu.self」。
  • Bundle Identifier(套件識別碼): com.appcoda.StackViewDemo - 這是你的App的唯一識別碼,在App 送審時會用到。你不需要填入這個選項,Xcode 會自動幫你產生。
  • Interface: Storyboard - 如前解釋,Xcode 現在支援兩種 UI 建構方式,這裡請選擇「Storyboard」,因為本書會採用 UIKit 與 Storyboard 來開發 UI。
  • Language(語言): Swift – 我們會使用Swift來開發專案。
  • Use Core Data(使用Core Data): [unchecked] – 不用勾選—此選項不要勾選,此專案不會用到Core Data。
  • Include Tests: [unchecked] – 不用勾選—這個選項不要勾選,此專案不會進行任何測試。

點選「Next」按鈕,接著 Xcode 會詢問你要將 StackViewDemo 專案儲存至哪裡,在你的 Mac 電腦上挑選一個資料夾,並點選「Create」按鈕來繼續。

加入圖片至 Xcode 專案中:

如你所見,這個範例 App 包含了三張圖片。問題是你該如何將三張圖片整合進去 Xcode 專案中?

在每一個 Xcode 專案中,它包含了一個素材目錄(也就是 Assets.xcassets ),來管理你的App 中會用到的圖片以及圖示,如圖6.3 所示。至專案導覽器並選取 Assets.xcassets 資料夾,它預設是空的,也就是說 AppIcon組是空白的。本章並不打算介紹 App 圖示,但是我們在之後建立一個真實世界的 App 時會再來看此部分。

圖 6.3 素材目錄
圖 6.3 素材目錄

現在開啟本章所準備的圖片組(https://www.appcoda.com/resources/swift4/stackviewdemo-images.zip ),並將其解壓縮至Mac 中, 這個壓縮檔總包含了 5 個圖檔:

Credit: 圖片是由 usersinsights.com 所提供。

iOS 支援兩種類型的圖檔:「點陣圖」(raster image )以及「向量圖」(vector image )。一般像是 PNG 與JPEG 都歸為點陣圖。點陣圖是使用像素網格來形成一個完整的圖片。點陣圖會有放大後的品質問題,將點陣圖片放大後,通常會失真。因此 Apple 建議開發者在使用PNG 時,提供三種不同解析度的圖片。以這個例子而言,檔名user2 有三種版本。字尾加上x 表示擁有較高解析度,是給i Phone 8 Plus、iPhone 14/15 Pro 與 iPhone 14/15 Pro Max 使用;字尾加上 x,則是給 iPhone SE/8/11 使用的;而若是沒有@作為字尾的話, 則表示針對非視網膜螢幕的舊裝置(例如:iPad 2)。如果有興趣了解圖片是如何被運用的細節,你可以進一步參考下列的連結: https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/image-size-and-resolution/

向量圖的檔案格式通常是 PDF 或是 SVG,你可以使用像是 Sketch 與 Pixelmator 的工具來建立向量圖。和點陣圖不同的是,向量圖是以路徑所組成,而不是由像素所組成,其圖檔可以放大而不會失真。由於這個功能,你只需要提供一個 PDF 檔格式給 Xcode 即可。

為了示範,我打算加入這兩種圖檔,實際在開發一個 App 時,通常你只會使用到其中一種圖檔。那麼何種類型的圖檔較好呢?如果可以的話,要求你的設計者準備 PDF 檔, 檔案不但會比較小,且不會因為縮放而失真。

要加入圖檔至素材目錄的話,你只需要將這些圖片從資料夾拖曳至套圖清單或套圖檢視器中,如圖 6.4 所示。

圖 6.4. 加入圖片至素材目錄

當你將圖片加至素材目錄中後,套圖視圖會自動歸類這些圖片至不同的位置中,如圖 6.5 所示。之後,如果要使用某張圖片,你只需要使用該圖片的套圖名稱(例如:user1) 即可。你可省略檔名,即使相同的圖片有不同的版本(例如:user2)。你不用擔心該使用哪個版本(@2x/@3x)的圖片,這些全部都是由 iOS 自己分類處理。

圖 6.5. 圖片自動歸類

以堆疊視圖來佈局標題標籤

現在你已經將所需的圖片匯入了專案中,我們將進行堆疊視圖的實作。首先,開啟 Main.storyboard,我們開始這兩個標籤的佈局,如圖 6.6 所示。

圖 6.6. 範例App 的標題以及副標題標籤

堆疊視圖可以在垂直與水平佈局中排列多個視圖(也就是所謂的排列視圖),因此你一開始必須決定是否需要使用垂直堆疊視圖或者水平堆疊視圖。由於標題以及副標題標籤是以垂直方向來排列,因此垂直堆疊視圖顯然是比較合適的選擇。

我習慣在 iPhone 14/15 Pro 來佈局,但實際上你可以使用任何裝置來佈局。不過,為了跟著本章的內容實作,於設定列點選裝置標示,並確認你目前為使用 iPhone 14/15 Pro。請點選「+」按鈕來開啟元件庫,並從元件庫中拖曳一個 Vertical Stack View 物件至 Storyboard 內的視圖控制器,如圖 6.7 所示。

註: 儘管螢幕截圖中可能顯示使用的是 iPhone 14 Pro,但在使用 Xcode 15 時,請選擇 iPhone 15 Pro。

圖 6.7. 加上一個垂直堆疊視圖至視圖控制器中

接著,從元件庫中拖曳一個標籤並置於堆疊視圖中。當你將標籤放進堆疊視圖之後, 堆疊視圖會自動將它嵌入,並調整它自己的大小來相容這個標籤,如圖 6.8 所示。在標籤上點選兩下,將標題改為「Instant Developer」。在屬性檢閱器(Attribute Inspector )中, 將 Font Size 處改為「40 點」,Font Style 處改為「Medium」。另外,你也可以將顏色改為「System Indigo Color」或任何你偏好的顏色。

現在,從元件庫中拖曳另一個標籤至堆疊視圖中。接著放開該標籤,堆疊視圖將嵌入新標籤,並垂直排列兩個標籤,如圖 6.8 所示。

圖 6.8. 嵌入兩個標籤至垂直堆疊視圖中

編輯這個新標籤的標題,變更為「Get help from experts in 15 minutes」。如果你有做對, 這兩個標籤應該置於堆疊視圖內,你可以在文件大綱中確認這些物件。

現在,這兩個標籤已經對齊於堆疊視圖的左側。當你想要變更它的對齊形式,你可以變更這個堆疊視圖內建的屬性來改變其外觀。選取堆疊視圖,你可以在屬性檢閱器(Attributes Inspector )中找到它的屬性,如圖6 .9 所示。

圖 6.9. 堆疊視圖的屬性範例
圖 6.9. 堆疊視圖的屬性範例

這裡提醒一下,若是你在選取堆疊視圖時有任何困難,你可以按住鍵,並在堆疊視圖上按右鍵。介面建構器會顯示一個快捷選單來讓你選擇,如圖 6.10 所示。另外,你也可以在文件大綱中選擇堆疊視圖,這兩種方法都可行。

圖 6.10. 快捷選單
圖 6.10. 快捷選單

以下簡短地說明堆疊視圖的每一個屬性:

  • 「Axis」選項:是指示要將排列視圖以垂直或者水平
  • 「Alignment」選項:是控制排列視圖如何對齊。舉例而言,如果它是設定為「Leading」,這個堆疊視圖會對齊排列視圖的前緣(也就是左側)。
  • 「Distribution」選項:定義了排列視圖的尺寸以及位置。預設是設定為「Fill」。以這個例子而言,這個堆疊視圖試著盡力在它的可用空間內相容所有的子視圖。若它是設定為「Fill Equally」,這個垂直堆疊視圖會將兩個標籤平均分布,所以在同一個垂直軸上都會有相同的大小。

圖 6.11 列出一些不同屬性的佈局範例。

圖 6.11. 堆疊視圖屬性的快速示範
圖 6.11. 堆疊視圖屬性的快速示範

針對我們的範例 App,我們只是將 Alignment 選項由「Fill」改為「Center」,並保持其他選項不變,這會使得標籤保持置中。

在進入下一節之前,請確認你已經將堆疊視圖正確設定好,這會有利於你跟上接下來的內容。你可以選取堆疊視圖,然後至尺寸檢閱器中確認你已將X 值設定為「41」,Y 值設定為「70」,如圖 6.12 所示。

圖 6.12 確認堆疊視圖的位置
圖 6.12 確認堆疊視圖的位置

使用堆疊按鈕來佈局圖片

在前面的內容中,我提到了有兩種使用堆疊視圖的方式。剛才你從元件庫中加入了堆疊視圖。現在我要介紹另外一種方法。

現在我們準備要佈局三個使用者圖片。在 iOS 中,我們使用圖片視圖來呈現圖片。在元件庫中尋找Image View 物件,並拖曳它來加入視圖。當你加入圖片視圖之後,選擇屬性檢閱器,圖片選項已經自動從素材(Asset )目錄載入。只要將它設定為 user1,在尺寸檢閱器中,設定圖片的寬度為 100、高度為 134,如圖 6.13 所示。

圖 6.13. 加入一個圖片視圖以顯示圖片
圖 6.13. 加入一個圖片視圖以顯示圖片

重複相同的步驟來加入其他兩張圖片視圖,並將它們並排一起。但是分別設定第二張圖片為 user2以及第三張圖片為 user3。你的佈局會如圖 6.14 所示。

圖 6.14. 指定圖片至圖片視圖
圖 6.14. 指定圖片至圖片視圖

使用堆疊視圖可以減少佈局約束條件的定義,但這並不表示你不需要定義任何自動佈局約束條件。針對這些圖片視圖,我們希望它們的長寬比(Aspect Ratio )都能保持。之後,圖片尺寸會依照螢幕尺寸而有所變動,我們希望不管是被拉長或者壓縮,都能夠固定長寬比。

想要這麼做的話,如圖 6.15 所示,在文件大綱視圖中,按住鍵從 user1 這個圖片視圖來水平拖曳。在快捷選單中,選取 Aspect Ratio,接著針對其他兩張圖片視圖執行相同的步驟。

圖 6.15. 加上長寬比的約束條件
圖 6.15. 加上長寬比的約束條件

現在我要使用堆疊視圖群組這三個圖片視圖,如此一來,便可方便管理。不過,我會用另外一種替代方法來建立堆疊視圖。

按住 command 鍵並點選三個圖片視圖來選取它們,然後點選佈局選單中的「Embed in」按鈕,並選取「Stack View」,介面建構器會自動地將這些圖片視圖嵌入至水平堆疊視圖中, 如圖 6.16 所示。

圖 6.16. 在水平堆疊視圖中群組圖片視圖
圖 6.16. 在水平堆疊視圖中群組圖片視圖

想要在圖片視圖間加入一些間距,則選取堆疊視圖並將間距設定為 20

現在你已經有兩個堆疊視圖:一個是放標籤的堆疊視圖,另外一個則是圖片視圖。這些堆疊視圖實際上可以結合在一起方便處理。很棒的是,你可以將多個堆疊視圖嵌入在一起。

要如此做時,從文件大綱視圖選取兩個堆疊視圖,然後點選「Embed in」按鈕,並選取「Stack View」,便可以將兩個堆疊視圖嵌入一個垂直堆疊視圖中,如圖 6.17 所示。接著, 確認這個新的堆疊視圖的 Alignment 屬性是設定為「Fill」。透過將 Alignment 屬性設定為「Fill」,可以讓圖片視圖隨著螢幕變大而自動調整大小。當我們在iPad 上預覽這個 UI 時, 你便會了解我的意思。

圖 6.17. 嵌入堆疊視圖
圖 6.17. 嵌入堆疊視圖

很酷,對吧?至目前為止,UI 在 iPhone 14/15 Pro 看起來很不錯。不過,如果是在其他裝置上預覽UI,則會結果不如預期,原因是我們還沒有定義堆疊視圖的佈局約束條件。

對堆疊視圖定義佈局約束條件

對於堆疊視圖,我們會定義以下的佈局約束條件:

  • 設定它自己與頂部佈局導引之間的間距約束條件,如距離安全區域佈局導引的頂部50 點。
  • 設定一個在堆疊視圖左側與安全區域的前緣之間的間距約束條件,如它們之間的間距為10 點。
  • 設定一個在堆疊視圖右側與安全區域後緣之間的間距約束條件,如它們之間的間距為10 點。

現在至佈局列點選「Add New Constraint」按鈕。設定上方、左側與右側的間距約束條件,分別為「50、10、10」,如圖 6.18 所示。當約束條件啟用之後,它是以紅實線來標示。然後點選「Add 3 Constraints」按鈕來加入約束條件。

圖 6.18. 使用Pin 按鈕來加入多個約束條件
圖 6.18. 使用Pin 按鈕來加入多個約束條件

當你加入約束條件之後,介面建構器會自動重新調整堆疊視圖至正確的位置,以符合你的佈局約束條件,如圖 6.19 所示。

圖 6.19. 加入間距約束條件後的堆疊視圖位置
圖 6.19. 加入間距約束條件後的堆疊視圖位置

現在試著在其他裝置上預覽介面。看起來應該很正確,不過你可能會注意到一個問題:

在 iPhone SE,這個「Instant Developer」的標籤被截斷了,如圖 6.20 所示。

圖 6.20. 在iPhone SE 上預覽UI
圖 6.20. 在iPhone SE 上預覽UI

所以該如何修正這些問題呢?

顯然地,我們可以縮小標籤的字型大小。Xcode 提供了一個動態自動調整字型的方式。現在選取「Instant Developer」標籤,並至屬性檢閱器,將「Autoshrink」選項設定為「Minimum Font Size」,然後將值設定為 20,如圖 6.21 所示。

圖 6.21. 變更標籤的自動縮小(Autoshrink )選項
圖 6.21. 變更標籤的自動縮小(Autoshrink )選項

這個動作是告知 Xcode(或者 iOS )自行判斷,以讓標籤完美顯示的合適大小。在設定列中,選取 iPhone SE 來測試 UI。現在標籤應該能夠完整顯示了。

在圖片下方加入標籤

在圖片下方還有一個標籤沒有加入,我故意留到這裡才示範,這可以讓你了解把物件加到目前的堆疊視圖中是很容易的一件事。

開啟元件庫,拖曳一個標籤物件至存放其他兩個堆疊視圖的堆疊視圖中,你會見到一條指示插入位置的藍色線,如圖 6.22 所示。

圖 6.22. 加入新標籤至目前的堆疊視圖
圖 6.22. 加入新標籤至目前的堆疊視圖

接著,選取新標籤,至屬性檢閱器中設定以下這段文字:

Need help with coding problems? Register!

另外,變更文字為置中,如圖 6.23 所示對齊。

圖 6.23. 變更文字為置中對齊
圖 6.23. 變更文字為置中對齊

現在 UI 在所有裝置上看起來還不錯。如你所見,堆疊視圖節省了定義新標籤的約束條件,它繼承了你稍早所定義的約束條件。

使用堆疊視圖佈局按鈕

我們還沒有完成,將會繼續在畫面下方佈局兩個按鈕。

首先,點選 + 按鈕來開啟元件庫,並從元件庫拖曳一個按鈕至視圖。點選按鈕兩下, 以命名為「Sign up」。在屬性檢閱器中,將樣式設定為「Filled」。iOS 15 內置多款按鈕樣式, Filled 樣式允許您快速創建具有純色背景和圓角的按鈕。

另外,將背景顏色改為「System Indigo Color」,編輯字型選項,設定大小為「20」點。樣式設為粗體(bold )。

要使按鈕更大一點,你可以轉到尺寸檢查器並將「Size」選項更改為 Large。如想將按鈕變得更大,可將寬度設定為 200。高度設為 50 點。

接下來,我們來建立「Log In」按鈕,為了省略這些重複的步驟,你可以選取按鈕並按下command - D 來進行複製,然後將新按鈕調整位置位於「Sign Up」按鈕的下方,接著修改名稱為「Log In」,在屬性檢閱器中,變更背景顏色為「System Gray Color」。如圖 6.24 所示。

圖 6.24. 增加兩個按鈕至視圖中
圖 6.24. 增加兩個按鈕至視圖中

同樣的,你不需要幫這些按鈕設定佈局約束條件,就讓堆疊視圖為你展現神奇魔法。按住 command鍵,並選取兩個按鈕,然後點選在佈局列的「Embed in」按鈕,並選取「Stack View」,來將兩個按鈕群組起來並嵌入一個垂直堆疊視圖中。接下來,將堆疊視圖水平置中,要為按鈕之間增加間距的話,則選取堆疊視圖,在屬性檢閱器中將「Spacing」的值設定為 10

以同樣的做法,我們必須定義這個堆疊視圖的佈局約束條件,讓它的位置靠近視圖底部。以下是我們準備要定義的佈局約束條件:

  • 將堆疊視圖相對於容器視圖為水平置中對齊。
  • 設定間距約束條件,讓堆疊視圖與安全區域的底部之間有間距。

選取剛才建立的堆疊視圖,點選佈局列中的「Align」按鈕。勾選「Horizontally in Container」選項,然後點選「Add 1 Constraint」,如圖 6.25 所示。

圖 6.25. 增加一個新的約束條件,以讓堆疊視圖水平置中
圖 6.25. 增加一個新的約束條件,以讓堆疊視圖水平置中

接下來,加入一個間距約束條件,點選「Add New Constraints」按鈕並設定底部的值為 30。確認該列已呈現為紅實線。點選「Add 1 Constraint」來加入約束條件,如圖 6.26 所示。

圖 6.26. 增加一個間距約束條件至堆疊視圖中
圖 6.26. 增加一個間距約束條件至堆疊視圖中

有一件事你可能會注意到,就是按鈕比預期中狹窄。當你將按鈕嵌入堆疊視圖中,它們會調整它原先的尺寸。當你想要設定寬度為「200」,你需要加入一個尺寸約束條件至堆疊視圖。在文件視圖中,按住鍵後,從堆疊視圖往自己拖曳以帶出內容選單,然後選取「Width」來加入寬度約束條件,如圖 6.27 所示。

圖 6.27. 使用 command 鍵加上拖曳來加入寬度約束條件
圖 6.27. 使用 command 鍵加上拖曳來加入寬度約束條件

在約束條件加入完成之後,你應該會在文件大綱中見到這些約束條件,展開它來顯示寬度約束條件,因為我們需要將寬度變更為 200 點,選取寬度約束條件,並至屬性檢閱器,將約束條件值改為 200,現在堆疊視圖的寬度已經固定為 200 點了。如圖 6.28 所示。

圖 6.28. 編輯寬度約束條件為「200」
圖 6.28. 編輯寬度約束條件為「200」

這兩個按鈕高度為 50 點,你可能會想,我們需要為這兩個按鈕加入高度約束條件, Xcode 可以讓你為多個物件同時加入相同的約束條件。以這個例子為例,你可以按著 鍵不放,並選取這兩個按鈕,然後點選「Add new constraints」按鈕並設定高度為 50,當你確認加入約束條件後,Xcode 會將這個約束條件一次加在這兩個按鈕上,如圖 6.29 所示。

圖 6.29. 同時為兩個按鈕加入高度約束條件
圖 6.29. 同時為兩個按鈕加入高度約束條件

是時候再度來測試 App 了。你可以在介面建構器預覽你的 UI,或者在不同裝置執行這個專案。現在 UI 在所有裝置上都能完美呈現了,如圖 6.30 所示。

圖 6.30. 在iPhone SE 中預覽UI
圖 6.30. 在iPhone SE 中預覽UI

你是否注意到「Need help with coding problems? Register!」這個訊息在 iPhone SE 被截斷了?試著自己修復看看。若是你不知道該如何解決這個問題,請回到前一節去尋找答案。

使用尺寸類別讓堆疊視圖自適應

現在你已經採用堆疊視圖建立了一個很不錯的 UI,不過是否已測試過橫向模式呢?當你將 iPhone(或 iPad )模擬器轉向,UI 在橫向模式時的樣子,如圖 6.31 所示。

圖 6.31. App UI 分別在 iPhone 11 Pro(左圖)與iPad Pro 12.9 英吋(右圖)橫向模式的呈現樣貌
圖 6.31. App UI 分別在 iPhone 11 Pro(左圖)與iPad Pro 12.9 英吋(右圖)橫向模式的呈現樣貌

目前 UI 在 iPad 上看起來非常好,但是在 iPhone 上就顯得有點奇怪,有幾個地方可以做修正,來讓它看起來更好看:

  1. 稍微移動一下整個堆疊視圖,讓它靠近視圖的上緣。
  2. 這些圖片太大了,所以中間的圖片和按鈕重疊。

要注意的是,這些改變只會在iPhone 的橫向模式上實施,那麼該如何做呢?

這會導引至由 iOS 8 所導入的新UI 設計觀念, 稱作「自適應佈局」(Adaptive Layout)。有了自適應佈局,你的App 可以讓 UI 只特別對某個裝置或者裝置方向來調整。

要做到自適應佈局,Apple 導入了一個新觀念,稱作「尺寸類別」(Size Classes ),這大概是自適應佈局的一個最重要觀念了。尺寸類別的概念,即一個裝置如何依照它的螢幕尺寸與方向來做分類。你可以同時使用尺寸類別以及自動佈局來設計自適應使用者介面。

尺寸類別指出了垂直(高度)與水平(寬度)尺寸的顯示空間的相對量。有兩種尺寸類別型態:「Regular」與「Compact」,「Regular」尺寸類別是表示較大的螢幕空間, 「Compact」尺寸類別則表示較小的螢幕空間。

使用一個尺寸類別來描述每一個顯示裝置的尺寸,結果可以把裝置歸納為四類:「Regular width-Regular Height」、「Regular width-Compact Height」、「Compact width- Regular Height」與「Compact width-Compact Height」。

圖 6.32 為iOS 裝置與其相對應的尺寸類別。

圖 6.32. 尺寸類別
圖 6.32. 尺寸類別

要表達一個顯示的環境,你需要指定一個水平尺寸類別(Horizontal Size Class )以及一個垂直尺寸類別(Vertical Size Class )。例如:一個 iPad 可以用 Regular 的水平(也就是Width )尺寸類別以及一個 Regular 的垂直(也就是Height )尺寸類別。以我們的例子而言,我們想要特別對 iPhone 在橫向模式來佈局。換句話說,這裡我們需要處理兩個尺寸類別:

  • Compact width-Compact height
  • Regular width-Compact height

了解尺寸類別後,現在回到 Main.storyboard。在設定列中,將裝置設定為橫向模式。接下來,選取安全區域頂部與堆疊視圖頂部之間的間距約束條件。在屬性檢閱器中,點選「Constant」選項旁的 +按鈕。選取「Any Width → Compact height → Any Gamut」, 然後設定尺寸類別的值為 -40,如圖 6.33 所示。

Quick note: 在這裡,「Any Width」是指包含了 Compact 與 Regular 的寬度。
圖 6.33. 加上一個特定尺寸類別約束條件
圖 6.33. 加上一個特定尺寸類別約束條件

如此一來,堆疊視圖與視圖頂部之間的間距在 iPhone 轉向時便會縮小。請在介面建構器做 UI 的預覽,或者在不同的 iOS 裝置上執行這個專案,並看一下結果為何,你應該會注意到這個間距約束條件只有當裝置是 iPhone 且為橫向模式時才會減少。

現在我們來看第二個問題,以了解如何在 iPhone 為橫向模式時能夠縮小圖片的尺寸。

你不只可以自訂約束條件,Xcode 讓你可以為堆疊視圖定義特定尺寸類別屬性。選取存放在其他堆疊視圖的主堆疊視圖。

圖 6.34. 自訂堆疊視圖
圖 6.34. 自訂堆疊視圖

在屬性檢閱器中,點選 Alignment 旁的 + 按鈕來加入新的自訂條件。選取「Any」width、「Compact」height 與「Any」Gamut, 然後點選「Add Variation」, 這可以讓你自訂對齊條件,如圖6.34 所示。將「hC」欄位設為「Center」。在橫向方向(只有 iPhone ),我們將保持對齊為「Center」,如此圖片便不會調整尺寸,如圖 6.35 所示。

圖 6.35. 自訂對齊條件後的結果
圖 6.35. 自訂對齊條件後的結果

目前在 iPhone 橫向模式看起來更棒了。不過「Need help with coding problems? Register!」這個訊息還是有一個問題,它依然被按鈕蓋住了。要解決這個問題,讓我介紹另一個使用尺寸類別的方法。

選取存放「Sing Up」與「Log In」這兩個按鈕的堆疊視圖,在屬性檢閱器,點選 Axis 旁的 +按鈕。於 Width 選取「Any」,Height 則選取「Compact」。並點選「Add Variation」來確認。新的 hC 欄位,設定為 Horizontal,這表示 iPhone 在橫向模式時, 要以水平方式取代垂直方式來排列,如圖 6.36 所示。

圖 6.36. 為 Axis 選項加入佈局規格
圖 6.36. 為 Axis 選項加入佈局規格

現在「Need help」訊息不再被按鈕蓋住了,不過,我們還需要調整另一件事。我們必須調整一些約束條件以使 UI 看起來更好。 按鈕堆疊視圖的寬度限制為 200 。 選擇約束並添加另一個自訂條件。 再次,選擇 Any 寬度和 Compact 高度,然後單點 Add VariationConstant 選項。 在新的 hC 字段中,將其值設置為 300。

圖 6.37. 自訂隱藏屬性
圖 6.37. 自訂隱藏屬性

進行更改後,兩個按鈕的大小相同。 它還沒有完成。 選擇堆疊視圖的底部間距約束。 再次,選擇 Any 寬度和 Compact 高度,然後單點 Add VariationConstant 選項。 在新的 hC 字段中,將其值設置為「0」。

圖 6.38. 為底部空間約束添加自定義
圖 6.38. 為底部空間約束添加自定義

就是如此 !你可以在不同模擬器中再次執行這個App。使用者介面應該能夠針對不同螢幕大小方向做調整。

保存向量資料

在我結束本章之前,我要介紹一個 Xcode 的功能,也就是「保存向量資料」(Preserve Vector Data )。我曾提過,在 iOS 開發中,比起使用點陣圖,我們比較傾向使用向量圖, 因為向量圖不管怎麼縮放圖片也不會失真。

當向量圖被使用時,Xcode 會自動將圖片轉換為靜態圖片(@1x、@2x、@3x ),這很像我們準備好的 user2 圖片,但是轉換工作由Xcode 來進行。在這個例子中,當圖片變大時,品質稍微會受到影響。如果你試著在iPad Pro(12.9 英吋)執行這個範例,你應該會發現圖片的品質不佳。

Xcode 內建了「保存向量資料」的功能,可以讓你保存圖片的向量資料。預設上,這個功能是關閉的,要啟動它的話,你可以至 Assets.xcassets,並選取其中一張圖片,在屬性檢閱器中勾選「Preserve Vector Data」前的核取方塊,來啟用這個選項,如圖 6.39 所示。

圖 6.39. 啟用「保存向量資料」功能
圖 6.39. 啟用「保存向量資料」功能

現在當你在 iPad Pro(12.9 英吋)執行這個 App,你會發現圖片的品質看起來較好,圖 6.40 示範啟用這個功能前後的圖片差異。

圖 6.40. 停用「保存向量資料」功能(左圖)以及啟用「保存向量資料」功能(右圖)
圖 6.40. 停用「保存向量資料」功能(左圖)以及啟用「保存向量資料」功能(右圖)

作業 #1

為了要幫助你更加了解自動佈局與尺寸類別的內容,我們有一個簡單的作業。你需要更新一些約束條件,並建立另一個針對 iPhone/iPad 的佈局規範。以下是所需規格:

  • 對於所有裝置,將「Sign Up」與「Log in」按鈕的寬度從「200 點」變更為「300 點」。
  • 針對iPad,增加「Instant Developer」標籤的字體大小為「65 點」。
圖 6.41. 作業#1 的 UI
圖 6.41. 作業#1 的 UI

作業 #2

若是作業1對你而言太過簡單了,你可以嘗試作業 2 ,試著建立一個如圖 6.42 所示的 UI。你可以使用本章為您所準備的圖片(http://www.appcoda.com/resources/swift4/student-tutor.zip )。

圖 6.42. 作業#2 的UI
圖 6.42. 作業#2 的UI

Credit: 背景圖片由 Luka Dadiani 所提供

作業 #3

還有一個作業讓你自行練習所學的內容,試著建立一個如圖 6.43 的 UI,你可以使用任何自己的圖片來建立使用者介面,有個功能我還沒介紹過,那就是標籤元件,不過這個作業你需要使用它,標籤是設定為顯示一行文字,如果你需要顯示多行文字,你可以變更「Lines」選項的值,譬如說,如果要顯示兩行文字,你只要將值設定為 2 即可。

圖 6.43. 作業#3的 UI
圖 6.43. 作業#3的 UI

本章小結

恭喜 !你已經完成了本章,並學習到如何使用堆疊視圖與尺寸類別建立一個自適應 UI。

堆疊視圖以最少的約束條件簡化了 iOS 建立使用者介面的方式。你可能會想問:什麼時候該使用堆疊視圖呢? Apple 的工程師建議開發者先採用堆疊視圖,然後到時候視實際需求使用約束條件即可。因此本書我們將全部使用堆疊視圖來設計使用者介面。


本文摘自《iOS 17 App程式設計實戰心法》(Swift+UIKit)》一書。如果你想更深入學習Swift程式設計和下載完整程式碼,你可以從 AppCoda網站 購買完整電子版。

results matching ""

    No results matching ""