SwiftUI 框架

利用 Searchable 修飾符 輕鬆在 SwiftUI List 視圖中實作搜尋欄

iOS 15 推出前,SwiftUI 並沒有內置修飾符來在 List 視圖中處理搜尋,開發者需要創建自己的解決方案。在 iOS 15 中,SwiftUI 框架為 List 視圖帶來了一個名為 searchable 的新修飾符。在這篇文章中,我會帶大家看看這個新修飾符如何簡化實作搜尋欄的步驟,並為我們節省時間。
利用 Searchable 修飾符 輕鬆在 SwiftUI List 視圖中實作搜尋欄
利用 Searchable 修飾符 輕鬆在 SwiftUI List 視圖中實作搜尋欄
In: SwiftUI 框架

在 iOS 15 推出之前,SwiftUI 並沒有內置修飾符來在 List 視圖中處理搜尋,開發者需要創建自己的解決方案。我們還寫了一篇教學文章,教大家利用 TextField 來打造一個搜尋欄 (search bar),並顯示搜尋結果。在 iOS 15 推出之後,SwiftUI 框架為 List 視圖帶來了一個名為 searchable 的新修飾符 (modifier)。

在這篇教學文章中,我們會探討這個修飾符,看看為一個 List 實作搜尋有多簡單!

Searchable 的基本使用

Search-bar-ios15-demo

假設你已經創建了一個 List 視圖來顯示一系列文章,並希望提供一個搜尋欄來過濾文章。要將搜尋欄添加到 List 視圖,我們只需要宣告一個狀態變數 (state variable),來保存搜尋文本 (search text),並附加 searchable 修飾符到 NavigationView 即可:

struct SearchListView: View {

    @State var articles = sampleArticles
    @State private var searchText = ""

    var body: some View {
        NavigationView {
            .
            .
            .
        }
        .searchable(text: $searchText)
    }
}

SwiftUI 會自動幫我們呈現搜尋欄,並將其放在 Navigation Bar 標題下。

swiftui-searchable-search-bar

在預設情況下,它會顯示 Search 為佔位符 (placeholder)。如果想更改它,你可以如此編寫 .searchable 修飾符,並設置自己的佔位符。

.searchable("Search articles...", text: $searchText)

搜尋欄的位置

.searchable 修飾符有一個 placement 參數 (parameter),用於指定搜尋欄的位置。在預設情況下,它會設置為 .automatic。在 iPhone 上,搜尋欄位於 Navigation Bar 標題的下方。當我們向上滾動 List 視圖時,搜尋欄就會被隱藏。

searchable-permanent-search-bar-placement

如果想像上面這樣長期顯示搜尋欄,我們可以更改 .searchable 修飾符,並如此指定 placement 參數:

.searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always))

我們一直都將 .searchable 修飾符附加到 Navigation 視圖,其實我們也可以將它附加到 List 視圖,這樣在 iPhone 上都可以達到相同的效果。

不過,在 iPad OS 上使用 Splitview 時,.searchable 修飾符的位置就會影響搜尋欄的位置。讓我們看看下面的範例程式碼:

NavigationView {
    List {
        ForEach(articles) { article in
            ArticleRow(article: article)
        }

        .listRowSeparator(.hidden)

    }
    .listStyle(.plain)

    Text("Article Content")


    .navigationTitle("AppCoda")

}
.searchable(text: $searchText)

平常我們將 .searchable 修飾符附加到 Navigation 視圖中,在這種情況下,搜尋欄會顯示在 Split 視圖的 sidebar 上。

searchable-on-ipados

如果我們想將搜尋欄放在 detail 視圖中呢?我們可以將 .searchable 修飾符附加到範例程式碼的 Text 視圖中。

Text("Article Content")
    .searchable(text: $searchText)

iPadOS 就會在 detail 視圖的右上角顯示搜尋欄。

searchable-ipados-search-bar

同樣,我們可以調整 placement 參數的值,來更改搜尋欄的位置。看看以下例子:

.searchable(text: $searchText, placement: .navigationBarDrawer)

如果我們把 placement 參數設置為 .navigationBarDrawer,iPadOS 就會將搜尋欄放置在 Navigation Bar 標題的下方。

searchable-ipados-navigationbardrawer

執行搜尋並顯示搜尋結果

searchable-perform-search

我們有很多種方法可以過濾 Data List。我們可以創建一個實時執行資料過濾的計算屬性;或是附加 .onChange 修飾符,以追踪搜尋欄的改變。每當使用者在搜尋欄輸入內容時,就會實時執行搜尋。看看以下的範例程式碼片段:

NavigationView {
    List {
        ForEach(articles) { article in
            ArticleRow(article: article)
        }

        .listRowSeparator(.hidden)

    }
    .listStyle(.plain)

    .navigationTitle("AppCoda")
}
.searchable(text: $searchText)
.onChange(of: searchText) { searchText in

    if !searchText.isEmpty {
        articles = sampleArticles.filter { $0.title.contains(searchText) }
    } else {
        articles = sampleArticles
    }
}

添加搜尋建議

我們可以利用 .searchable 修飾符來添加搜尋建議列表,以顯示一些常用的搜尋字詞或搜尋歷史。舉個例子,你可以這樣創建可點擊 (tappable) 的搜索建議:

.searchable(text: $searchText) {
    Text("SwiftUI").searchCompletion("SwiftUI")
    Text("iOS 15").searchCompletion("iOS 15")
}

以上的程式碼會顯示搜尋建議,當中有兩個可點擊的搜尋字詞。使用者可以輸入搜尋關鍵字,或是點擊搜尋建議來執行搜尋。

searchable-swiftui-perform-search

總結

iOS 15 為 SwiftUI 框架帶來了另一個備受期待的功能。.searchable 修飾符簡化了實作搜尋欄的步驟,並讓我們不需要創建解決方案,為我們節省了時間。唯一的缺點是這個功能僅適用於 iOS 15(或更新版本)。如果你正在構建需要支持舊版本 iOS 的 App,就還是需要構建自己的搜尋欄

譯者簡介:Kelly Chan-AppCoda 編輯小姐。
原文How to Implement Search for SwiftUI List Using Searchable

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