SwiftUIで検索バーを表示する方法
2023-10-12 08:48:59
質問
新しいSwiftUIフレームワークは組み込みの検索バーコンポーネントを提供しないようです。UISearchControllerを使い、何らかの方法でラップするべきか、あるいは単純なテキストフィールドを使い、テキストフィールドの入力に従ってデータを更新すべきでしょうか?
EDIT: 現在のところ、回避策として
TextField
をsearchBarとして使用することです。これは非常にうまくいっていますが、検索アイコンがありません。
import SwiftUI
struct Search : View {
let array = ["John","Lena","Steve","Chris","Catalina"]
@State private var searchText = ""
var body: some View {
NavigationView{
List{
TextField("Type your search",text: $searchText)
.textFieldStyle(RoundedBorderTextFieldStyle())
ForEach(array.filter{$0.hasPrefix(searchText) || searchText == ""}, id:\.self){searchText in
Text(searchText)
}
}
.navigationBarTitle(Text("Search"))
}
}
}
struct Search_Previews : PreviewProvider {
static var previews: some View {
Search()
}
}
Xcode 11.1 で動作するように更新しました。
どのように解決するのですか?
以下は、純粋なswiftUIバージョンで、ベースは Antoine Weber の の質問に対する回答と、私が見つけた このブログ と この要旨 . を組み込んでいます。
- クリアボタン。
- キャンセルボタン
- リスト内のドラッグでキーボードを放棄し
- 検索テキスト フィールドが選択されると、ナビゲーション ビューを非表示にする。
リスト内でドラッグした際にキーボードを放棄することは、以下のUIApplicationウィンドウのメソッドを使用して実現することができます。 これらの回答 . より簡単に処理するために、私はUIApplicationの拡張機能とこの拡張機能のためのビューモディファイアを作成し、最終的にビューの拡張機能を作成しました。
extension UIApplication {
func endEditing(_ force: Bool) {
self.windows
.filter{$0.isKeyWindow}
.first?
.endEditing(force)
}
}
struct ResignKeyboardOnDragGesture: ViewModifier {
var gesture = DragGesture().onChanged{_ in
UIApplication.shared.endEditing(true)
}
func body(content: Content) -> some View {
content.gesture(gesture)
}
}
extension View {
func resignKeyboardOnDragGesture() -> some View {
return modifier(ResignKeyboardOnDragGesture())
}
}
つまり、キーボードを辞任するための最終的なモディファイアは、このようにリストに載せるだけでいいのです。
List {
ForEach(...) {
//...
}
}
.resignKeyboardOnDragGesture()
検索バーの完全なswiftUIプロジェクトコードと、名前のリストのサンプルは次のとおりです。新しいswiftUIプロジェクトのContentView.swiftに貼り付けて遊べます。
import SwiftUI
struct ContentView: View {
let array = ["Peter", "Paul", "Mary", "Anna-Lena", "George", "John", "Greg", "Thomas", "Robert", "Bernie", "Mike", "Benno", "Hugo", "Miles", "Michael", "Mikel", "Tim", "Tom", "Lottie", "Lorrie", "Barbara"]
@State private var searchText = ""
@State private var showCancelButton: Bool = false
var body: some View {
NavigationView {
VStack {
// Search view
HStack {
HStack {
Image(systemName: "magnifyingglass")
TextField("search", text: $searchText, onEditingChanged: { isEditing in
self.showCancelButton = true
}, onCommit: {
print("onCommit")
}).foregroundColor(.primary)
Button(action: {
self.searchText = ""
}) {
Image(systemName: "xmark.circle.fill").opacity(searchText == "" ? 0 : 1)
}
}
.padding(EdgeInsets(top: 8, leading: 6, bottom: 8, trailing: 6))
.foregroundColor(.secondary)
.background(Color(.secondarySystemBackground))
.cornerRadius(10.0)
if showCancelButton {
Button("Cancel") {
UIApplication.shared.endEditing(true) // this must be placed before the other commands here
self.searchText = ""
self.showCancelButton = false
}
.foregroundColor(Color(.systemBlue))
}
}
.padding(.horizontal)
.navigationBarHidden(showCancelButton) // .animation(.default) // animation does not work properly
List {
// Filtered list of names
ForEach(array.filter{$0.hasPrefix(searchText) || searchText == ""}, id:\.self) {
searchText in Text(searchText)
}
}
.navigationBarTitle(Text("Search"))
.resignKeyboardOnDragGesture()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
.environment(\.colorScheme, .light)
ContentView()
.environment(\.colorScheme, .dark)
}
}
}
extension UIApplication {
func endEditing(_ force: Bool) {
self.windows
.filter{$0.isKeyWindow}
.first?
.endEditing(force)
}
}
struct ResignKeyboardOnDragGesture: ViewModifier {
var gesture = DragGesture().onChanged{_ in
UIApplication.shared.endEditing(true)
}
func body(content: Content) -> some View {
content.gesture(gesture)
}
}
extension View {
func resignKeyboardOnDragGesture() -> some View {
return modifier(ResignKeyboardOnDragGesture())
}
}
検索バーの最終結果は、初期状態では次のように表示されます。
で、検索バーをこのように編集した場合。
動作中です。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン