【Swift UI】フィルター機能の実装方法!リストに検索ボックスを作成

この記事からわかること

  • Swift UIフィルター機能実装方法
  • リスト表示配列フィルタリングするには?
  • 検索ボックス作成する方法
  • containsメソッドとsearchableモディファイアの使い方

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

List構造体を使って表示しているビューにフィルター機能を実装する方法をまとめていきます。

フィルター機能を実装する方法

今回は要素に構造体を保持する配列をリスト表示している場合にフィルター機能を実装する方法を見ていきます。

struct ContentView: View {
    struct Lang:Identifiable{
        var id = UUID()
        var name:String
        var version:Double
    }
    let langArray = [Lang(name: "HTML", version: 5.0),Lang(name: "CSS", version: 3.0),Lang(name: "PHP", version: 8.1),Lang(name: "Swift", version: 5.4)]

    var body: some View {
        List(langArray) { item in
            HStack{
                Text(item.name)
                Spacer()
                Text("Version:\(String(format: "%.1f", item.version))")
            }
        }
    }
}
SwiftUIで要素に構造体を保持する配列をリスト表示しているビュー

ここにフィルター機能を実装するためにはfilterメソッドを使用します。

おすすめ記事:filterメソッドの使い方

filterメソッド使用例

var all = [
    Lang(name : "HTML", version : 5.0),
    Lang(name : "CSS", version : 3.0),
    Lang(name : "Swift", version : 5.4)
]
var searchLanguage = all.filter({ $0.version > 4 })
print(searchLanguage)
[__lldb_expr_37.Lang(id: 919B3A58-6E7A-485B-A442-99BA617D88FE, name: "HTML", version: 5.0), __lldb_expr_37.Lang(id: 497D31D0-A53E-4CF7-A1D1-62722269DA3D, name: "Swift", version: 5.4)]

要素のプロパティの値でフィルターをかける

例えばversionプロパティが4以上の言語だけを抽出して表示させるようにするためには以下のようにします。

 List(langArray.filter({$0.version > 4})) { item in
    HStack{
        Text(item.name)
        Spacer()
        Text("Version:\(String(format: "%.1f", item.version))")
    }
}

しかしこれでは常にフィルターがかかった状態になってしまうのでボタンでフィルターのON/OFFを切り替えられるようにしておきます。ON/OFFは真偽値を保持するプロパティとして定義しておき、ボタンクリック時に真偽値を入れ替えるようにしておきます。

@State  var isFilter:Bool = false // フィルターON/OFF真偽値
var body: some View {
    VStack {
        Button(action: {
            isFilter.toggle()
        }, label: {
            Text(isFilter ? "OFF" : "ON")
        })

        List(langArray.filter(isFilter ? {$0.version > 4} : {$0.version != 0})) { item in
            HStack{
                Text(item.name)
                Spacer()
                Text("Version:\(String(format: "%.1f", item.version))")
            }
        }
    }
}

ON/OFFの真偽値によってフィルターに渡す条件式を変更しています。OFFの場合は全ての要素にマッチするような条件を渡しています。

langArray.filter(isFilter ? {$0.version > 4} : {$0.version != 0})

検索ボックスを作成

SwiftUiで検索ボックスを作成してフィルタリングしている様子

リストに対して入力値を検索するための検索ボックスを作成するにはsearchableモディファイアとcontainsメソッドを活用します。searchableモディファイアを使用するためにNavigationViewでリストを囲みます。

@State  var text:String = ""
    
var body: some View {
    NavigationView{
            List(langArray.filter(text.isEmpty ? { $0.name != ""  } : { $0.name.contains(text)})) { item in
                HStack{
                    Text(item.name)
                    Spacer()
                    Text("Version:\(String(format: "%.1f", item.version))")
                }
            }.navigationTitle("言語")
    }.searchable(text: $text,prompt: "検索値")
}

バインディングするための変数を用意し、その変数の中身に応じてフィルタリングする条件を変更していきます。

langArray.filter(text.isEmpty ? { $0.name != ""  } : { $0.name.contains(text)})

containsメソッドは引数の文字が対象文字列内に存在するかしないかの真偽値を返すメソッドです。

検索ボックスがシミュレーターに表示されない場合はリストを下にスワイプすることで表示されるようになります。

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

私がSwift UI学習に使用した参考書

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index