【SwiftUI × CoreData 검색 필터링
전제 조건
며칠 전 SwiftUI× CoreData를 사용하여 CRUD 기능을 갖춘 메모장 애플리케이션을 제작했습니다.
나는 이 프로그램에 검색 기능을 추가할 것이다.
컨디션
Swift5
Xcode13.1
iOS15
(iOS15 이상
searchable
모뎀을 사용합니다.)검색 필터링 기능 구현
메모는 응용 프로그램의 소스 코드에서 표시 부분을 요약합니다.
import SwiftUI
import CoreData
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
entity: Memo.entity(),
sortDescriptors: [NSSortDescriptor(key: "updatedAt", ascending: false)],
animation: .default
) var fetchedMemoList: FetchedResults<Memo>
var body: some View {
NavigationView {
List {
ForEach(fetchedMemoList) { memo in
NavigationLink(destination: EditMemoView(memo: memo)) {
VStack {
Text(memo.title ?? "")
.font(.title)
.frame(maxWidth: .infinity,alignment: .leading)
.lineLimit(1)
HStack {
Text (memo.stringUpdatedAt)
.font(.caption)
.lineLimit(1)
Text(memo.content ?? "")
.font(.caption)
.lineLimit(1)
Spacer()
}
}
}
}
.onDelete(perform: deleteMemo)
}
.navigationTitle("メモ")
.navigationBarTitleDisplayMode(.automatic)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink(destination: AddMemoView()) {
Text("新規作成")
}
}
}
}
}
private func deleteMemo(offsets: IndexSet) {
offsets.forEach { index in
viewContext.delete(fetchedMemoList[index])
}
try? viewContext.save()
}
}
그러면 이 일람표시에 검색 기능을 추가합니다.
@State private var searchText: String = ""
searchable
모뎀 구현NavigationView {
// 省略
}
.searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always), prompt: "検索")
placement
에서 표시 위치를 결정할 수 있으며, 이번에는 자주 표시.navigationBarDrawer(displayMode: .always)
를 위해 사용한다.또한
prompt
를 통해 평면 유지기를 설정할 수 있다.onChange
에 입력할 때마다 검색 조건의 판정// searchableの下に追加
.onChange(of: searchText) { newValue in
search(text: newValue)
}
실시
onChange
에 명시된 search
방법CoreData는
NSPredicate
를 사용하여 검색 조건을 지정할 수 있습니다. private func search(text: String) {
if text.isEmpty {
fetchedMemoList.nsPredicate = nil // ①
} else {
let titlePredicate: NSPredicate = NSPredicate(format: "title contains %@", text) // ②
let contentPredicate: NSPredicate = NSPredicate(format: "content contains %@", text) // ③
fetchedMemoList.nsPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [titlePredicate, contentPredicate]) // ④
}
}
점① 검색이 비어 있을 경우 검색 조건을 필터링할 필요가 없음
②
%@
문자열로 처리한다는 뜻"title에 문자열 text 포함"을 검색 조건으로 합니다
③ "conent에 문자열 text 포함"을 검색 조건으로 함
④
NSCompoundPredicate
로 여러 조건 연결orPredicateWithSubpredicates
OR 조건으로 배열을 연결하는 내용이렇게 하면 제목이나 노트 내용이 검색 텍스트 부분과 일치하는 노트만 추출할 수 있다.
전체 이미지
import SwiftUI
import CoreData
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
entity: Memo.entity(),
sortDescriptors: [NSSortDescriptor(key: "updatedAt", ascending: false)],
animation: .default
) var fetchedMemoList: FetchedResults<Memo>
@State private var searchText: String = ""
var body: some View {
NavigationView {
List {
ForEach(fetchedMemoList) { memo in
NavigationLink(destination: EditMemoView(memo: memo)) {
VStack {
Text(memo.title ?? "")
.font(.title)
.frame(maxWidth: .infinity,alignment: .leading)
.lineLimit(1)
HStack {
Text (memo.stringUpdatedAt)
.font(.caption)
.lineLimit(1)
Text(memo.content ?? "")
.font(.caption)
.lineLimit(1)
Spacer()
}
}
}
}
.onDelete(perform: deleteMemo)
}
.navigationTitle("メモ")
.navigationBarTitleDisplayMode(.automatic)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink(destination: AddMemoView()) {
Text("新規作成")
}
}
}
}
.searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always), prompt: "検索")
.onChange(of: searchText) { newValue in
search(text: newValue)
}
}
private func deleteMemo(offsets: IndexSet) {
offsets.forEach { index in
viewContext.delete(fetchedMemoList[index])
}
try? viewContext.save()
}
private func search(text: String) {
if text.isEmpty {
fetchedMemoList.nsPredicate = nil
} else {
let titlePredicate: NSPredicate = NSPredicate(format: "title contains %@", text)
let contentPredicate: NSPredicate = NSPredicate(format: "content contains %@", text)
fetchedMemoList.nsPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [titlePredicate, contentPredicate])
}
}
}
참고 자료
Reference
이 문제에 관하여(【SwiftUI × CoreData 검색 필터링), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/tomsan96/articles/0a76b9b457dc6f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)