SwiftUI 框架

利用 SwiftUI 的 AnyLayout 幾行程式碼就可以切換 layout!

在 iOS 16,SwiftUI 推出 AnyLayout 和 Layout 協定,讓開發者構建客製化和複雜的 layout。有了 AnyLayout,我們可以創建回應使用者互動或環境變化的動態 layout。在這篇文章中,我們會試著使用 AnyLayout 來切換垂直和水平 layout。
利用 SwiftUI 的 AnyLayout 幾行程式碼就可以切換 layout!
Photo by Andrea De Santis on Unsplash
In: SwiftUI 框架

iOS 16 開始,SwiftUI 推出了 AnyLayoutLayout 協定,讓開發者構建客製化和複雜的 layout。AnyLayout 是 layout 協定的 type-erased 實例。我們可以使用 AnyLayout 來創建動態 layout,它可以回應使用者的互動或環境變化。

在這篇教學文章中,我們會看看如何使用 AnyLayout 來切換垂直和水平 layout。

使用 AnyLayout

首先,讓我們用 App 模板創建一個新的 Xcode 專案,並為專案命名,我會把專案命名為 SwiftUIAnyLayout。我們會構建一個簡單的範例 App,在使用者點擊堆疊視圖時切換 UI layout。UI layout 在不同方向看起來會是這樣的:

SwiftUI AnyLayout - Switch between HStack and VStack

在開始時,範例 App 利用 VStack 把三個圖像垂直排列。當使用者點擊堆疊視圖時,就會變成水平堆疊。我們可以這樣使用 AnyLayout 來實作:

struct ContentView: View {
    @State private var changeLayout = false

    var body: some View {
        let layout = changeLayout ? AnyLayout(HStackLayout()) : AnyLayout(VStackLayout())

        layout {
            Image(systemName: "bus")
                .font(.system(size: 80))
                .frame(width: 120, height: 120)
                .background(in: RoundedRectangle(cornerRadius: 5.0))
                .backgroundStyle(.green)
                .foregroundColor(.white)


            Image(systemName: "ferry")
                .font(.system(size: 80))
                .frame(width: 120, height: 120)
                .background(in: RoundedRectangle(cornerRadius: 5.0))
                .backgroundStyle(.yellow)
                .foregroundColor(.white)

            Image(systemName: "scooter")
                .font(.system(size: 80))
                .frame(width: 120, height: 120)
                .background(in: RoundedRectangle(cornerRadius: 5.0))
                .backgroundStyle(.indigo)
                .foregroundColor(.white)

        }
        .animation(.default, value: changeLayout)
        .onTapGesture {
            changeLayout.toggle()
        }
    }
}

我們定義了一個 layout 變數,來保存 AnyLayout 的實例。這個 layout 會根據 changeLayout 的數值,來切換水平和垂直 layout。HStackLayout(或 VStackLayout)的行為與 HStack(或 VStack)類似;但因為它符合 Layout 協定,我們就可以在 conditional layout 中使用它。

我們還可以把動畫附加到 layout,來動畫化佈局的改變。現在,當我們點擊堆疊視圖時,它就會切換垂直或水平 layout。

根據裝置的方向切換 layout

現在,範例 App 讓使用者點擊堆疊視圖來切換 layout。在某些 App 中,我們可能會想根據裝置方向和螢幕大小來切換 layout。在這個情況下,就可以利用 .horizontalSizeClass 變數來捕捉裝置方向的改變。

@Environment(\.horizontalSizeClass) var horizontalSizeClass

然後,讓我們如此更新 layout 變數:

let layout = horizontalSizeClass == .regular ? AnyLayout(HStackLayout()) : AnyLayout(VStackLayout())

舉個例子,如果我們把 iPhone 14 Pro Max 轉為橫向,layout 就會切換為橫向堆疊視圖。

swiftui anylayout demo

在大多數情況下,我們會使用 SwiftUI 內建的 layout container 來創建 layout,像是 HStackLayoutVStackLayout。但如果這些 layout container 無法實作我們需要的 layout 型別,該怎麼辦呢?iOS 16 引入的 Layout 協定就讓我們可以定義自己客製化的 layout。我們只需要創建一個符合 Layout 協定的型別,並實作以下所需的方法,來定義一個客製化的 layout container:

  • sizeThatFits(proposal:subviews:cache:):這個方法會報告合成 layout 視圖的大小。
  • placeSubviews(in:proposal:subviews:cache:):這個方法會為 container 的子視圖分配位置。

推出了 AnyLayout 後,我們只需要幾行程式碼就可以客製化或更改 UI layout,這絕對可以幫助我們構建更優雅和吸引的 UI。在這篇文章的範例 App 中,大家都學會了如何根據螢幕方向切換 layout。其實同樣的技術也可以應用於其他情況中,例如是 Dynamic Type 的大小。

備註:如果你有興趣深入學習 SwiftUI,並參閱所有源程式碼,歡迎看看我們的《精通 SwiftUI》一書,我們已為 iOS 16 和 Xcode 14 全面更新了這本書。

譯者簡介:Kelly Chan-AppCoda 編輯小姐。
作者
Simon Ng
軟體工程師,AppCoda 創辦人。著有《iOS 17 App 程式設計實戰心法》、《iOS 17 App程式設計進階攻略》以及《精通SwiftUI》。曾任職於HSBC, FedEx等跨國企業,專責軟體開發、系統設計。2012年創立AppCoda技術部落格,定期發表iOS程式教學文章。現時專注發展AppCoda業務,致力於iOS程式教學、產品設計及開發。你可以到推特與我聯絡。
評論
更多來自 AppCoda 中文版
iOS 18 新API:使用 Navigation Transition 創建 Hero 動畫式過場
SwiftUI 框架

iOS 18 新API:使用 Navigation Transition 創建 Hero 動畫式過場

Apple 的工程師可能早已認識到,許多 iOS 開發者都希望能夠重現 App Store 應用程式中的優雅 Hero 動畫。由於從頭實現這種動畫通常需要耗費大量時間與精力,Apple 在 iOS 18 SDK 中納入了這項功能。 透過這次更新,你現在只需少量的程式碼就能在自己的應用程式中實現類似的動畫過渡效果。這項重大改進讓開發者能夠創造出更具視覺吸引力且流暢的過渡效果,
如何使用 Vision APIs 從圖像中辨識文字
AI

如何使用 Vision APIs 從圖像中辨識文字

Vision 框架長期以來一直包含文字識別功能。我們已經有詳細的教程,向你展示如何使用 Vision 框架掃描圖像並執行文字識別。之前,我們使用了 VNImageRequestHandler 和 VNRecognizeTextRequest 來從圖像中提取文字。 多年來,Vision 框架已經顯著演變。在 iOS 18 中,Vision
iOS 18更新:SwiftUI 新功能介紹
SwiftUI 框架

iOS 18更新:SwiftUI 新功能介紹

SwiftUI的技術不斷演進,每次更新都讓 iOS 應用程式開發變得更加便捷。隨著 iOS 18 Beta 的推出,SwiftUI 引入了多個令人興奮的新功能,使開發者僅需幾行程式碼即可實現出色的效果。 本教學文章旨在探索這個版本中的幾項主要改進,幫助你了解如何運用這些新功能。 浮動標籤列 (Floating Tab Bar)SwiftUI中的標籤視圖(Tab
很好! 你已成功註冊。
歡迎回來! 你已成功登入。
你已成功訂閱 AppCoda 中文版 電子報。
你的連結已失效。
成功! 請檢查你的電子郵件以獲取用於登入的連結。
好! 你的付費資料已更新。
你的付費方式並未更新。