[iOS] Playgroundでsearchableを触ってみた

iOS14まではSwiftUIのModifierの中でUISearchBarのような要素がなかったため、SwiftUIで検索バーを実装するためにはUIKitのUISearchBarをUIViewRepresentableにして使うか、
SwiftUIのTextFieldをUISearchBarみたいにデザインして使うかといった選択肢がありましたが、どちらにしても色々と手間がかかる所がありました。

iOS15からはSwiftUIのNavigationViewからsearchableというModifierを指定できるようになりましたが、これがUISearchBarに相当するものです。

今回はsearchableをどうやって実装できるか確認したく、Playgroundで触ってみました。

Model

まずはModelを指定します。
適当に動物3匹を配列に入れます。

import PlaygroundSupport
import SwiftUI

// Model
struct AnimalIdentifiable {
   var id = UUID()
   var name: String
}

var animal = [
   Animal(name: "Dog"),
   Animal(name: "Cat"),
   Animal(name: "Bird")
]

View

1. 
モデルで指定したanimalのnameをViewのListから指定し、Textで表示するようにします。

// View
struct ContentViewView {
   var body: some View {
       List(animal) {
           Text($0.name)
       }
   }
}

2. 
検索バーを表示するためにNavigationViewをListの上にラップします。
その後、NavigationViewにsearchable modifierを指定します。

searchable
にはTextFieldのようにバインディング型のtextパラメータが入ります。
そのため、変数keywordを@Stateで宣言しました。

@State private var keyword = ""

var body: some View {
   NavigationView {
       List(animal) {
           Text($0.name)
       }
   }
   .searchable(text: $keyword)
}

ここまでくると、このようなレイアウトになります。
searchableの指定でUISearchBarのような検索バーが簡単に表示されます。

スクリーンショット 2022-03-31 15.23.15

次はListの要素を検索バーから実際に検索してみましょう。

3. 
animalの中で検索された動物を入れる配列updatedTextを宣言しました。
また、ListにonChange modifierを指定し、keywordが変わるたびにリストをアップデートするようにします。

onChangeの処理 
検索バーに入力されたkeywordが変わる際に、animalのname中からkeywordの文字が含まれているnameがあるかどうかを判断し、 その結果をupdatedTextの配列に入れます。

...
@State private var updatedText: [Animal] = []

...
List(keyword == "" ? animal: updatedText) {
   Text($0.name)
}
.onChange(of: keyword) { searchValue in
   updatedText = animal.filter { $0.name.contains(searchValue) }
}
...

これで検索もできるようになりました。

スクリーンショット 2022-03-31 17.43.58

最後に

現時点でSwiftUIのNavigationViewを用いた画面遷移パフォーマンスが優れるとは言えないため、画面遷移が必要な時はまだUIKitを使うしかない場面もあるかと思います。
そのため、今回紹介したsearchableも実際のサービスに実用される日はまだ先になるかと思いますが、今回Playgroundで試してみたらたった1行を追加することで検索バーを使えるようになったり、簡単に検索処理を書くことができたりしたので、これからSwiftUIがUIKitを超えメインになると開発スピードをかなりアップできそうと思いました。

今回に引き続き次はAPIを用いた検索処理にも挑戦してみたいと思います💪

参考


この記事が気に入ったらサポートをしてみませんか?