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

To the user, the interface is the product.

- Aza Raskin

我已經簡要介紹了 SwiftUI 的觀念,並向你展示如何處理一些基本的 UI 元件,其中包括垂直堆疊視圖(即 VStack )。我們建立的第一個 App 非常簡單,隨著 App 的 UI 變得更複雜時,將會需要使用不同型態的堆疊視圖來建立使用者介面,更重要的是,你需要學習如何建立可相容各式螢幕大小的 UI。

在本章中,我將會介紹所有類型的堆疊,並建立更全面的 UI,在真實世界所運用的 App 中,你可能看過這些 UI。此外,我將介紹另一種用來顯示圖片的常見 SwiftUI 元件。你將會學習到:

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

你會很驚訝使用堆疊視圖便可完成這麼多的工作。

VStack、HStack與 ZStack 介紹

SwiftUI 為開發者提供三種不同類型的堆疊,以組合不同方向的視圖。依據你要如何排列視圖,而可以使用:

  • HStack - 水平排列視圖。
  • VStack - 垂直排列視圖。
  • ZStack - 將一個視圖重疊在其他視圖之上。

圖 4.1 展示了如何使用這些堆疊來組織視圖。

圖 4.1. 不同型態的堆疊視圖
圖 4.1. 不同型態的堆疊視圖

範例 App

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

圖 4.2. 範例App p
圖 4.2. 範例App p

在前面的章節中,你已經使用了VStack 來垂直排列UI 元件,但是要建立App UI,你需要組合各種類型的堆疊視圖,如你所見,該App UI 在所有螢幕尺寸上都運作良好。如果你有使用過UIKit 的經驗,可能就會知道使用自動佈局來建立相容所有螢幕尺寸的UI 的必要性,而對初學者而言,自動佈局可能是一個複雜的主題且不易學習,好消息是SwiftUI 不再使用自動佈局,並簡化了編寫自適應UI 的過程,你很快就會明白我的意思。

建立新專案

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

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

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

加入圖片至 Xcode 專案中

你可能會注意到,範例 App 包含了三張圖片,問題是你該如何在Xcode 專案中綁定三張圖片呢?

在每個Xcode 專案中,都包含了一個素材目錄(即Assets ),用來管理你的 App 所使用的圖片及圖示,如圖4.3 所示。至專案導覽器並選取「Assets」資料夾,它預設的Appicon 與AccentColor 集是空的。本章並不會介紹App 圖示與強調色(Accent Color ),之後本書的其他章內容會複習這個部分。

圖 4.3. 素材目錄
圖 4.3. 素材目錄

現在下載本章所準備的圖片集 (https://www.appcoda.com/resources/swift4/stackviewdemo-images.zip) ,並將其解壓縮到Mac 中,這個壓縮檔包含了五個圖檔:

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

iOS 支援兩種類型的圖檔:「點陣圖」(Raster Image )及「向量圖」(Vector Image )。PNG 與 JPEG 等常見的圖片格式都歸類為點陣圖,點陣圖是使用像素網格來形成一個完整的圖片,它有放大後品質不佳的問題,將點陣圖片放大後,通常會失真,因此Apple 建議開發者在使用 PNG 時提供三種不同解析度的圖片。在本例中,圖檔共有三個版本,其中後綴為 @3x 的圖片擁有較高的解析度,適用於 iPhone 8 Plus、iPhone 14/15 Pro 與 iPhone 14/15 Pro Max;後綴為 @2x 的圖片,適用於 iPhone SE/8/14/15;而沒有後綴 @ 的圖片, 則適用非視網膜螢幕的舊裝置(例如:iPad 2)。如果有興趣了解如何使用圖片的細節, 你可以進一步參考下列的連結: (https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/image-size-and-resolution/).

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

為了示範,我故意在範例中加入這兩種圖檔,而開發一個真正的 App 時,你通常會使用其中一種圖檔。那麼,哪一種類型的圖檔比較好呢?如果可以的話,請你的設計師準備 PDF 格式的圖檔,整體檔案較小,且不會因為縮放而失真。

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

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

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

圖 4.5. 圖片自動歸類

使用堆疊視圖佈局標題標籤

現在你已經在專案中綁定必要的圖片,我們將繼續建立堆疊視圖。首先開啟 ContentView. swift,我們從這兩個標籤的佈局開始,如圖 4.6 所示。

圖 4.6. 範例App 的標題及副標題標籤

我相信你知道如何建立這兩個標籤,因為我們之前已經使用過 VStack。堆疊視圖可以在水平與垂直方向排列多個視圖。由於標題及副標題標籤是垂直排列,因此垂直堆疊視圖是較合適的選擇。

現在更新 ContentView 結構如下:

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Instant Developer")
                .fontWeight(.medium)
                .font(.system(size: 40))
                .foregroundStyle(.indigo)

            Text("Get help from experts in 15 minutes")
        }
    }
}

我們使用 VStack 來嵌入兩個 Text 視圖,如圖 4.7 所示。對於「Instant Developer」標籤, 我們設定固定的字型大小(例如:40 點)來使字體變大一點以及變更字型粗細來加粗文字; 要變更字型顏色,我們使用foregroundStyle 修飾器,並設定顏色為「.indigo」。

圖 4.7. 嵌入兩個標籤到垂直堆疊視圖中

使用留白與間距

預設上,這個堆疊視圖是顯示在螢幕的中央,不過如果你參見圖 4.2,這兩個標籤應該放置在靠近狀態列的位置,那麼我們該如何移動這兩個標籤呢?

訣竅是使用一個名為「留白」(Spacer )的特殊 SwiftUI 元件,留白視圖是一個沒有內容的視圖,它在堆疊視圖中占用儘可能多的空間,例如:當你將留白視圖放置在垂直佈局中,它會在堆疊允許的範圍內垂直擴展。

我們來看一下這個留白視圖的實際應用,如此你就會了解它如何幫助你排列 UI 元件。

要將兩個標籤推移到螢幕的上方,我們可以建立另一個 VStack(我們稱之為「根堆疊視圖」)來嵌入到目前的堆疊視圖中,然後加入一個 Spacer 視圖。

你可以按住鍵不放,然後在 VStack 上點擊,在內容選單中選擇「Embed in VStack」,Xcode 會自動將目前的VStack 包裹在另一個 VStack 中,如圖 4.8 所示。

圖 4.8. 將目前的VStack 嵌入到另一個VStack 視圖中
圖 4.8. 將目前的VStack 嵌入到另一個VStack 視圖中

接下來,在根堆疊視圖的右大括號之前插入 Spacer 視圖,如圖 4.9 所示。

圖 4.9. 加入留白到根堆疊視圖
圖 4.9. 加入留白到根堆疊視圖

當加入留白視圖後,它會展開以占據垂直堆疊視圖的所有可用空間,然後將標籤推到螢幕的頂部。

如果你仔細查看圖 4.2,你會發現這兩個標籤仍然沒有放置在預期的位置上,它現在離螢幕的頂部邊緣太近了,我們需要在邊緣與文字視圖之間留出一些間距才行。

在 SwiftUI 中,你可以使用padding 修飾器在視圖周圍增加間距。在此範例中,你可以加入 padding 修飾器到根VStack 視圖,如下所示:

VStack {

  .
  .
  .

}
.padding(.top, 30)

padding 修飾器接受兩個可選型別的參數,你可以指定要填入的邊緣與間距量,這裡我們告知 SwiftUI 於頂部邊緣加入間距,並設定間距量為「30 點」,如圖 4.10 所示。

圖 4.10. 為頂部邊緣加入間距
圖 4.10. 為頂部邊緣加入間距

在 SwiftUI 中,間距對於排列視圖的佈局非常有用,透過將間距應用在視圖中,你可以在不同視圖之間加入一些間距。

使用圖片

接下來,我們將佈局三個使用者圖片。在 SwiftUI 中,我們使用一個名為「Image」的視圖來顯示圖片。由於我們已經將圖片匯入素材目錄中,你可以編寫程式碼如下,以在螢幕上顯示圖片:

Image("user1")

你不需要指定檔案副檔名(例如:png / jpg / pdf),你只需要告知 Image 視圖圖片名稱。要將圖片視圖放置在文字視圖下的話,你可以在 Spacer() 前面插入上列的程式碼,如圖 4.11 所示。

圖 4.11. 加入圖片視圖來顯示圖片
圖 4.11. 加入圖片視圖來顯示圖片

預設上,iOS 會以原始大小來顯示圖片。要在 SwiftUI 中調整圖片大小,則我們可以加入 resizable 修飾器,如下所示:

Image("user1")
    .resizable()

iOS 會延伸圖片來填滿可用區域,圖 4.12 顯示了此修飾器的效果。

圖 4.12. 使用resizable 修飾器
圖 4.12. 使用resizable 修飾器

此延伸模式並沒有考量圖片本身的長寬比,它只是延伸每一邊來填滿整個視圖區域。要保持原來圖片的長寬比,則你可以應用 scaledToFit 修飾器如下:

Image("user1")
    .resizable()
    .scaledToFit()

或者,你可以使用 aspectRatio 修飾器,並設定內容模式為「.fit」,也可達到相同的結果。

Image("user1")
    .resizable()
    .aspectRatio(contentMode: .fit)

當你應用這些修飾器後,圖片將自動調整大小,並保持長寬比,如圖 4.13 所示。

圖 4.13. 使用scaledToFit
圖 4.13. 使用scaledToFit

使用水平堆疊視圖來排列圖片

現在你應該了解如何顯示圖片,我們來看如何將三張圖片並排在一起。之前我們使用 VStack 來垂直排列視圖,SwiftUI 框架提供另一種名為「HStack」的堆疊視圖來水平排列視圖。

使用 HStack 視圖來包裹 Image 視圖,並加入其他兩個視圖,如下所示:

HStack {
    Image("user1")
        .resizable()
        .scaledToFit()

    Image("user2")
        .resizable()
        .scaledToFit()

    Image("user3")
        .resizable()
        .scaledToFit()
}

當你將這些圖片視圖嵌入水平堆疊時,它會從左至右來並排放置圖片,如圖 4.14 所示。

圖 4.14. 並排排列圖片視圖
圖 4.14. 並排排列圖片視圖

圖片堆疊太靠近畫面的左右邊緣了,若要加入一些間距,則我們可以加入 padding 修飾器到 HStack,如下所示:

HStack {
  .
  .
  .
}
.padding(.horizontal, 20)

這告知 iOS 要在 HStack 視圖的左右邊緣加入 20 點的間距,如圖 4.15 所示。

圖 4.15. 將padding 修飾器加到水平堆疊中
圖 4.15. 將padding 修飾器加到水平堆疊中

我想要對水平堆疊視圖進行一些調整:

  1. 如果你仔細觀看這些圖片,它們並不是完全對齊的,我們想要將所有的圖片都與堆疊 視圖的底部邊緣對齊。
  2. 我們在這些圖片之間加入一些間距。

HStack 視圖實際上提供兩個可選型別的參數,一個是 alignment,另一個則是 spacing。透過為這些參數傳送一個適當的值,我們便可輕鬆完成上述的需求。

我們變更 HStack 的初始設定如下:

HStack(alignment: .bottom, spacing: 10) {
  .
  .
  .
}

這告知水平堆疊視圖將所有的圖片視圖對齊底部邊緣,並在視圖之間加入10 點的間距。

圖片現在已經完美對齊,而且看起來更加好看,對吧?

在圖片下方加入標籤

我們尚未在圖片下方加入標籤,這個實作應該非常簡單。你可以在 Spacer() 視圖之前插入下列的程式碼:

Text("Need help with coding problems? Register!")

正如圖 4.16 的預覽所示,文字視圖與圖片視圖靠得太近了。與 HStack 類似,VStack 也接受一個名為「spacing」的參數,可讓你為堆疊視圖中的項目加入一些間距。

圖 4.16. 在圖片下方加上標籤
圖 4.16. 在圖片下方加上標籤

現在更新根 VStack 視圖如下,以指定間距:

VStack(spacing: 20) {
  .
  .
  .
}

你應該注意到圖片堆疊視圖與文字視圖現在已經分開了,如圖 4.17 所示。

圖4.17. 對垂直堆疊視圖加入間距
圖4.17. 對垂直堆疊視圖加入間距

使用堆疊視圖佈局按鈕

我們還沒有完成,接下來繼續在螢幕底部佈局兩個按鈕,這兩個按鈕的固定寬度為「200 點」。

要建立紫色背景的「Sign Up」按鈕時,程式碼可以編寫如下:

Button {

} label: {
    Text("Sign Up")
}
.frame(width: 200)
.padding()
.foregroundStyle(.white)
.background(.indigo)
.clipShape(RoundedRectangle(cornerRadius: 10))

你應該很熟悉這些程式碼了,因為它和建立「Hello World」按鈕的程式碼非常相似。對你來說,比較陌生的地方是 frame 修飾器,它用來將按鈕的寬度限制為「200 點」。

同樣的,要建立「Sign Up」與「Log In」按鈕的佈局時,我們將按鈕嵌入到 VStack 視圖中,如下所示:

VStack {
    Button {

    } label: {
        Text("Sign Up")
    }
    .frame(width: 200)
    .padding()
    .foregroundStyle(.white)
    .background(.indigo)
    .clipShape(RoundedRectangle(cornerRadius: 10))

    Button {

    } label: {
        Text("Log In")
    }
    .frame(width: 200)
    .padding()
    .foregroundStyle(.white)
    .background(.gray)
    .clipShape(RoundedRectangle(cornerRadius: 10))
}

你可以將程式碼放在 Spacer() 視圖的後面,當完成變更後,你應該會在預覽窗格中看到兩個按鈕,如圖 4.18 所示。

圖 4.18. 加入按鈕
圖 4.18. 加入按鈕

設定預覽名稱與橫向預覽

Xcode 使用我們所選擇的模擬器來顯示UI 預覽,例如:我選擇「iPhone 15 Pro」作為模擬器,如果你選擇其他的模擬器,Xcode 會使用你所選擇的模擬器來渲染預覽。

預設上,預覽名稱設定為「Preview」,如果你想要使用不同的名稱該如何做呢?

我們來看一下預覽的程式碼:

#Preview {
    ContentView()
}

這段程式碼是為了產生 ContentView 的預覽而編寫的。#Preview 巨集提供了許多可選參數來供開發者自訂預覽。

更新預覽的程式碼如下:

#Preview("ContentView") {
    ContentView()
}

在上列的程式碼中,我們指定預覽名稱為「ContentView」,如果你查看預覽畫布,可能會注意到相應的名稱已經變更,如圖 4.19 所示。

圖 4.19. 更新模擬器的名稱
圖 4.19. 更新模擬器的名稱

另一個常見的問題是我們如何在預覽畫布中旋轉裝置?如果你需要橫向檢查 App UI, 你可以為 #Preview 插入另一個程式碼區塊。在 ContentView.swift 中插入下列的程式碼:

#Preview("ContentView (Landscape)", traits: .landscapeLeft) {
    ContentView()
}

程式碼修改後,預覽窗格應該會顯示兩個標籤:「ContentView」與「ContentView (Landscape)」,這是一個非常棒的功能,可讓你預覽 UI,並評估其在兩個方向上的效果, 如圖 4.20 所示。

圖 4.20. 在橫向模式下預覽 UI
圖 4.20. 在橫向模式下預覽 UI

另外,你可以使用 「Variants」按鈕,並選取「Orientation Variants」,以直向模式及橫向模式來預覽 UI。此選項提供了一個額外的方式來評估 UI 在不同裝置方向下的外觀和功能。

取出視圖使程式碼有更好的結構

在我們繼續佈局UI 之前,讓我先教你一個組織程式碼的技巧。當你要建立一個包含多個元件的更複雜 UI 時,ContentView 中的程式碼最後會變成一個難以查看及除錯的巨大程式碼區塊,最佳的作法是將大塊的程式碼拆分成更小的程式碼區塊,如此程式碼會更易於閱讀及與維護。

Xcode 內建了重構 SwiftUI 程式碼的功能,例如:如果我們要將存放「Sign Up」與「Log In」按鈕的 VStack 取出,你可以按住鍵並點擊VStack,然後選擇「Extract Subview」來取出程式碼,如圖 4.21 所示。

圖 4.21. 將Vstack 提取到子視圖
圖 4.21. 將Vstack 提取到子視圖

Xcode取出程式碼區塊,並建立一個名為「ExtractedView」的預設結構。將「ExtractedView」重新命名為「VSignUpButtonGroup」,以賦予其更有意義的名稱,詳見圖 4.22。

圖 4.22. 重新命名子視圖
圖 4.22. 重新命名子視圖

這是開發 SwiftUI App 時非常有用的技術,透過將程式碼取出到單獨的子視圖中,你的程式碼結構現在更有條理了。看一下 ContentView 中的程式碼,它現在已經更簡潔且更易於閱讀。

使用尺寸類別調整堆疊視圖

你對如圖 4.20 所示的 App 橫向佈局有何看法呢?該佈局在 iPhone 裝置上看起來不佳, 要解決這個問題,你可以考慮並排放置按鈕,如此可釋出一些空間來放大圖片,並提升整體的設計,如圖 4.23 所示。

圖 4.23. 並排按鈕
圖 4.23. 並排按鈕

請記住,這些改變只適用於iPhone 橫向模式,對於 iPhone 直向模式,兩個按鈕的位置則保持不變,那麼你該如何做呢?

這會導引到一種名為「自適應佈局」(Adaptive Layout )的UI 設計觀念,透過自適應佈局,你的 App 可以讓 UI 自適應特定裝置或裝置方向。

要實作自適應佈局,Apple 引入一個名為「尺寸類別」(Size Classes )的觀念,這大概是使自適應佈局成為可能的一個最重要觀念了。「尺寸類別」是依據裝置的螢幕尺寸與方向來對裝置做分類。

尺寸類別識別垂直(高度)與水平(寬度)尺寸的顯示空間的相對量,其有兩種尺寸類別類型:「常規」(Regular)與「緊湊」(Compact),常規尺寸類別表示較大的螢幕空間, 緊湊尺寸類別則表示較小的螢幕空間。

透過使用尺寸類別來描述每個顯示尺寸,這將產生四個裝置象限:「常規寬度- 常規高度」(Regular width-Regular Height )、「常規寬度- 緊湊高度」(Regular width-Compact Height )、「緊湊寬度- 常規高度」(Compact width- Regular Height )、「緊湊寬度- 緊湊高度」(Compact width-Compact Height )。

圖 4.24 顯示了 iOS 裝置及其相對應的尺寸類別。

圖 4.24. 尺寸類別
圖 4.24. 尺寸類別

要表達一個顯示環境,你必須同時指定水平尺寸類別(Horizontal Size Class )以及垂直尺寸類別(Vertical Size Class )。例如:iPad 具有常規的水平(寬度)尺寸類別以及常規的垂直(高度)尺寸類別。對於我們的自訂條件,我們希望為 iPhone 提供特定的橫向佈局,換句話說,當垂直尺寸類別設定為「緊湊」(compact)時,我們可以改變按鈕的佈局。

那麼,我們如何才能找出裝置的垂直尺寸類別呢?SwiftUI 框架提供@Environment 屬性包裹器(Property Wrapper )來取得垂直尺寸類別,你可以插入下列的程式碼來取得目前的尺寸類別

@Environment(\.verticalSizeClass) var verticalSizeClass

當裝置方向發生變化,verticalSizeClass 的值就會自動更新。

使用這個變數,我們可以參考 verticalSizeClass 的值來變更按鈕群組的佈局。你可以將 VSignUpButtonGroup() 替換為下列的程式碼:

if verticalSizeClass == .compact {
    HSignUpButtonGroup()
} else {
    VSignUpButtonGroup()
}

當垂直尺寸類別設定為「.compact」時,我們透過呼叫 HSignUpButtonGroup() 來將按鈕群組水平對齊,這裡的HSignUpButtonGroup() 是我們將要實作的新視圖。

現在插入下列的程式碼來建立 HSignUpButtonGroup 視圖:

struct HSignUpButtonGroup: View {
    var body: some View {
        HStack {
            Button {

            } label: {
                Text("Sign Up")
            }
            .frame(width: 200)
            .padding()
            .foregroundStyle(.white)
            .background(.indigo)
            .clipShape(RoundedRectangle(cornerRadius: 10))

            Button {

            } label: {
                Text("Log In")
            }
            .frame(width: 200)
            .padding()
            .foregroundStyle(.white)
            .background(.gray)
            .clipShape(RoundedRectangle(cornerRadius: 10))
        }
    }
}

HSignUpButtonGroup 的程式碼與 VSignUpButtonGroup 的程式碼幾乎相同,我們只需將 VStack 更改為HStack,即可並排佈局兩個按鈕。當你進行變更後,預覽應該會相應更新 UI,對於 iPhone 橫向模式,按鈕應該能水平對齊了,如圖 4.25 所示。

圖 4.25. 在iPhone 橫向模式時,按鈕會水平對齊
圖 4.25. 在iPhone 橫向模式時,按鈕會水平對齊

現在 UI 於 iPhone 橫向上看起來更好了,這就是我們如何利用尺寸類別來提供特定 UI,並對不同的螢幕大小微調UI 的方式。

保存向量資料

在我總結本章之前,我要介紹一個 Xcode 的功能, 即「保存向量資料」(Preserve Vector Data )。如前所述,在 iOS 開發中,我們比較傾向使用向量圖而不是點陣圖,因為向量圖不管怎麼縮放,圖片也不會失真,不過要注意的是這只有部分正確。

使用向量圖時,Xcode 會自動將圖片轉換為靜態圖片(@1x、@2x、@3x ),它非常類似於我們準備好的user2 圖片,但轉換工作是由 Xcode 處理,在這種情況下,放大圖片時,圖片品質會稍微受到影響。如果你試著在 iPad Pro(12.9 英吋)執行這個範例,則應該會發現圖片的品質不佳。

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

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

現在,如果你再次在 iPad Pro(12.9 英吋)執行這個App,你會發現圖片的品質看起來好多了,圖 4.27 示範了啟用或停用該選項的圖片差異。

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

你的作業:建立新 UI

為了幫助你更加了解堆疊視圖與尺寸類別的工作原理,我們來進行一個練習,請試著去建立一個如圖4.28 所示的 UI,你可以從下列網址下載所需的圖片: http://www.appcoda.com/resources/swift4/student-tutor.zip

圖 4.28. 作業的 UI 要求
圖 4.28. 作業的 UI 要求

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

給你一個提示,要實作背景圖片,你可以加上 background 修飾器如下:

VStack {
  .
  .
  .
}
.background {
    Image("background")
        .resizable()
        .ignoresSafeArea()
}

在修飾器內,你可以放置圖片作為背景,而 Image 視圖的 ignoresSafeArea 修飾器會將圖片擴展到整個螢幕。當你進行練習時,你就會了解我的意思。

本章小結

恭喜 !你已經完成本章,並掌握了如何使用堆疊視圖與尺寸類別來建立自適應 UI 的技能。

「堆疊視圖」是 SwiftUI 框架提供的極其強大的視圖元件,透過組合 VStack、HStack、ZStack,你可以輕鬆建立自適應不同螢幕尺寸的複雜 UI。本章只是對堆疊視圖進行介紹,之後當我們建立一個真實世界的 App 時,你將進一步學會更多使用堆疊視圖的高階佈局技術。


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

results matching ""

    No results matching ""