SwiftUI 框架

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

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

Apple 的工程師可能早已認識到,許多 iOS 開發者都希望能夠重現 App Store 應用程式中的優雅 Hero 動畫。由於從頭實現這種動畫通常需要耗費大量時間與精力,Apple 在 iOS 18 SDK 中納入了這項功能。

透過這次更新,你現在只需少量的程式碼就能在自己的應用程式中實現類似的動畫過渡效果。這項重大改進讓開發者能夠創造出更具視覺吸引力且流暢的過渡效果,進而提升應用程式的整體使用者體驗。

在本教程中,我們將探討如何利用新的 NavigationTransition 協定(protocol)以及 matchedTransitionSource 修飾符來在視圖過渡期間創建 Hero 動畫。

簡單的示範應用程式

讓我們透過一個示範應用程式來探索這些新 API。我們將從一個顯示咖啡廳列表的標準捲動視圖開始。我們的目標是實現一個功能,讓使用者點擊咖啡廳後,能夠進入顯示完整圖片的新畫面,並伴隨 Hero 動畫效果。

使用 Navigation Transition 協定

要顯示完整圖片並使用 Hero 動畫來進行視圖過場,可以按照以下步驟進行:

  1. 將捲動視圖嵌入到導航堆疊(navigation stack)中。
  2. 使用 NavigationLink 來啟用卡片視圖的點擊功能。
  3. 宣告一個帶有 @Namespace 的命名空間,以支援 Hero 動畫。
  4. matchedTransitionSource 修飾符附加到摘要模式的卡片視圖上。
  5. navigationTransition 修飾符附加到完整內容模式的卡片視圖上。

完成這些步驟後,SwiftUI 將自動產生一個流暢的 Hero 動畫,當點擊選中的咖啡廳項目時,會將其擴展為全螢幕圖片。

為視圖過場創建 Hero 動畫

現在我們將修改專案以支援導航功能。首先,將捲動視圖嵌入到導航堆疊中,如下所示:

NavigationStack {
	ScrollView {
	
		// Existing code
		
	}
}

接下來,建立一個用於顯示完整圖片的詳細視圖,如下所示。這個視圖會接受一個咖啡廳物件作為輸入,並在全螢幕視圖中顯示其圖片。

struct DetailView: View {
    var cafe: Cafe
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        Image(cafe.image)
            .resizable()
            .scaledToFill()
            .frame(minWidth: 0, maxWidth: .infinity)
            .clipped()
            .overlay(alignment: .topTrailing) {
                Button {
                    dismiss()
                } label: {
                    Image(systemName: "xmark.circle.fill")
                        .font(.system(size: 30))
                        .foregroundStyle(Color.white)
                        .opacity(0.7)
                        .padding()
                        .padding(.top, 30)
                }
            }
            .ignoresSafeArea()
    }
}

為了啟用與咖啡廳圖片的互動,我們可以使用 NavigationLink 來管理導航功能。當被點擊時,應用程式會顯示詳細視圖,並以全螢幕方式呈現圖片。

ForEach(sampleCafes) { cafe in
    
    NavigationLink {
        DetailView(cafe: cafe)
        
    } label: {
        Image(cafe.image)
            .resizable()
            .scaledToFill()
            .frame(minWidth: 0, maxWidth: .infinity)
            .frame(height: 400)
            .clipShape(RoundedRectangle(cornerRadius: 20))
    }
    .padding()
}

在預覽模式下,你可以在詳細視圖與列表視圖之間進行導航。此時,過渡效果使用的是導航堆疊的預設動畫,並未加入任何自訂效果。

現在來到有趣的部分了。我們將使用新的 NavigationTransition 協定來創建 Hero 動畫。第一步是為動畫定義一個命名空間。在 ContentView 中,宣告以下命名空間變數:

@Namespace var namespace

接著,將 matchedTransitionSource 修飾符應用到來源視圖,也就是列表中的圖片視圖。然後,在詳細視圖上使用 navigationTransition 修飾符。按照下面的程式碼更新你的應用程式:

NavigationLink {
    DetailView(cafe: cafe)
        .navigationTransition(.zoom(sourceID: cafe.id, in: namespace))
        .toolbarVisibility(.hidden, for: .navigationBar)
    
} label: {
    Image(cafe.image)
        .resizable()
        .scaledToFill()
        .frame(minWidth: 0, maxWidth: .infinity)
        .frame(height: 400)
        .clipShape(RoundedRectangle(cornerRadius: 20))
        .matchedTransitionSource(id: cafe.id, in: namespace)
}

為了增強視覺體驗,我還加入了 toolbarVisibility 修飾符來隱藏導航列。這樣可以移除返回按鈕,呈現一個更具沉浸感的全螢幕咖啡廳圖片展示。

在預覽模式下,測試應用程式,點擊咖啡廳圖片時,將會顯示帶有 Hero 動畫的全螢幕圖片。要返回列表,可以點擊「X」按鈕或直接向下拖動圖片。應用程式會將圖片以動畫方式還原到列表中的原始位置,提供一個流暢且直觀的使用者體驗。

總結

新的 NavigationTransition 協定讓開發者能夠輕鬆地創建視圖過渡的 Hero 動畫,只需幾行的程式碼便能提供更豐富的使用者體驗。建議你探索這個新功能,來提升應用程式的互動性和使用者滿意度。

需要注意的是,這個 API 僅適用於 iOS 18 及之後的版本。如果你的應用程式需要支援舊版 iOS,你將需要自行實作這個動畫。我們的《精通 SwiftUI》一書提供了如何實現這類效果的詳細指導。

作者
Simon Ng
軟體工程師,AppCoda 創辦人。著有《iOS 17 App 程式設計實戰心法》、《iOS 17 App程式設計進階攻略》以及《精通SwiftUI》。曾任職於HSBC, FedEx等跨國企業,專責軟體開發、系統設計。2012年創立AppCoda技術部落格,定期發表iOS程式教學文章。現時專注發展AppCoda業務,致力於iOS程式教學、產品設計及開發。你可以到推特與我聯絡。
評論
更多來自 AppCoda 中文版
如何使用 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 中文版 電子報。
你的連結已失效。
成功! 請檢查你的電子郵件以獲取用於登入的連結。
好! 你的付費資料已更新。
你的付費方式並未更新。