CoreDataのエンティティを検索フィールドを使用してフィルタする方法を紹介します。
検索フィールドは、serchableモディファイアを使用するため、iOS 15.0以上の環境で動作します。
前提条件
今回紹介しているコードは、検索部分のみです。
データの追加処理などは別途実装済であることが前提です。
コード例
| iOS | 15.0以上 |
| XCode(当サイトの環境) | 13.4.1 |
import SwiftUI
import CoreData
struct SerchSample: View {
// CoreDataのStaffエンティティをプロパティとして準備する
@FetchRequest(
entity: Staff.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \Staff.name, ascending: true)],
animation: .default
) private var fetchedStaff: FetchedResults<Staff>
// 検索テキストを格納するプロパティ
@State var text = ""
var body: some View {
NavigationView {
// Staffエンティティの情報をリスト表示する
List{
ForEach(fetchedStaff) { staff in
Text(staff.name ?? "")
}
}
}
// 検索フィールドを表示する
.searchable(text: $text, placement: .navigationBarDrawer(displayMode: .always), prompt: "検索するテキスト")
// 検索フィールドの値が変更されるごとに"serchResults"を呼び出す
.onChange(of: text) { newValue in
searchResults(text: newValue)
}
}
// 検索フィールドに入力された値により
// 取得したStaffにフィルタをかける
private func searchResults(text: String) {
// 検索フィールドが空ならフィルタなし
if text.isEmpty {
fetchedStaff.nsPredicate = nil
} else {
// nameアトリビュートにtextの文字列が含まれているかというフィルタを作成
let namePredicate: NSPredicate = NSPredicate(format: "name contains %@", text)
// staffエンティティにフィルタを適用(複数条件も適用可能)
fetchedStaff.nsPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [namePredicate])
}
}
}

