💬

SwiftUIを用いた検索画面(searchable, searchScopes, searchSuggestions)

2022/10/04に公開

SwiftUIを用いた検索画面

標準のメールアプリでの検索画面をSwiftUIで再現してみたいと思います。

簡単にするために犬の検索機能を実装します。

以下の3つを使ってUIを実装していきます。

標準メールアプリ 検索機能の要件

  • 検索していない時には全て表示
  • 検索文字列が空の時には検索履歴を表示
  • すべてのメールボックス現在のメールボックスで検索スコープを設定できる
  • 検索バーに文字を入力したら検索候補を表示
  • 検索ボタンを押した際に、検索に引っかかったものを表示
検索していない時 検索している時 検索文字列が空の時

作成するアプリ

検索していない時 検索している時 検索文字列が空の時

searchable

.searchable(text: $searchText)

searchScopes

.searchScopes($dogType) {
  ForEach(DogType.allCases) { type in
    Text(type.rawValue).tag(type)
  }
}

searchSuggestions

searchSuggestions下ではListで表示されているようなので、Sectionが使用できます。
ListswipeActions

.searchSuggestions {
if searchText.isEmpty && !searchHistory.isEmpty {
  Section("History") {
    ForEach(searchHistory, id: \.self) { history in
      Label(history, systemImage: "clock.arrow.circlepath")
	.searchCompletion(history)
	.swipeActions(edge: .trailing, allowsFullSwipe: true) {
	  Button(role: .destructive) {
	    searchHistory.removeAll { $0 == history }
	  } label: {
	    Text("Delete")
	  }
	}
    }
  }
}

if !searchText.isEmpty && !matchedDogs.isEmpty {
  Section("Suggest") {
    ForEach(matchedDogs) { dog in
      DogCell(dog: dog)
	.searchCompletion(dog.name)
    }
  }
}
}

onSubmit

// エンター押した際に履歴に追加
.onSubmit(of: .search) {
  if !searchHistory.contains(searchText) {
    searchHistory.append(searchText)
  }
}

ソースコード

全体のコードはGistに乗っけておきました

https://gist.github.com/zunda-pixel/5d71a03101e864b0a7bdc21b9cc1710c

Discussion