Saya mencoba menerapkan kode pencarian di aplikasi iPhone berbasis CoreData saya. Saya tidak yakin bagaimana melanjutkan. Aplikasi ini sudah memiliki NSFetchedResultsController dengan predikat untuk mengambil data untuk TableView primer. Saya ingin memastikan saya berada di jalan yang benar sebelum saya mengubah terlalu banyak kode. Saya bingung karena begitu banyak contoh berbasis array bukan CoreData.
Berikut ini beberapa pertanyaan:
Apakah saya perlu memiliki NSFetchedResultsController kedua yang hanya mengambil item yang cocok atau dapatkah saya menggunakan yang sama dengan TableView primer?
Jika saya menggunakan yang sama, apakah semudah membersihkan cache FRC dan kemudian mengubah predikat di handleSearchForTerm: metode searchString? Apakah predikat tersebut harus berisi predikat awal dan juga istilah pencarian atau apakah ia ingat bahwa predikat itu digunakan untuk mengambil data?
Bagaimana saya kembali ke hasil semula? Apakah saya hanya menetapkan predikat pencarian ke nihil? Bukankah itu akan membunuh predikat asli yang digunakan untuk mengambil hasil FRC di tempat pertama?
Jika ada yang punya contoh kode menggunakan pencarian dengan FRC, saya akan sangat menghargainya!
Jawaban:
Saya sebenarnya baru saja mengimplementasikan ini pada salah satu proyek saya (pertanyaan Anda dan jawaban salah lainnya mengisyaratkan apa yang harus dilakukan). Saya mencoba jawaban Sergio tetapi memiliki masalah pengecualian ketika benar-benar berjalan pada perangkat.
Ya, Anda membuat dua pengendali hasil ambil: satu untuk tampilan normal dan satu lagi untuk tampilan tabel UISearchBar.
Jika Anda hanya menggunakan satu FRC (NSFetchedResultsController) maka UITableView asli (bukan tampilan tabel pencarian yang sedang aktif saat mencari) mungkin akan memiliki panggilan balik yang dipanggil saat Anda mencari dan mencoba menggunakan versi FRC yang difilter dan Anda akan melihat pengecualian dilemparkan tentang jumlah bagian yang salah atau baris di bagian.
Inilah yang saya lakukan: Saya memiliki dua FRC yang tersedia sebagai properti fetchedResultsController dan searchFetchedResultsController. SearchFetchedResultsController tidak boleh digunakan kecuali jika ada pencarian (ketika pencarian dibatalkan, Anda dapat melihat di bawah ini bahwa objek ini dilepaskan). Semua metode UITableView harus mencari tahu tampilan tabel apa yang akan dicari dan dari FRC yang berlaku untuk menarik informasi. Metode delegasi FRC juga harus mencari tahu tableView mana yang akan diperbarui.
Sungguh mengejutkan betapa banyak dari ini adalah kode boilerplate.
Bit file header yang relevan:
relevan bit dari file implementasi:
Saya membuat metode yang bermanfaat untuk mengambil FRC yang benar ketika bekerja dengan semua metode UITableViewDelegate / DataSource:
Delegasikan metode untuk bilah pencarian:
pastikan bahwa Anda menggunakan tampilan tabel yang benar ketika mendapatkan pembaruan dari metode delegasi FRC:
Informasi tampilan lainnya:
Kode pembuatan FRC:
sumber
searchFetchedResultsController
untuknil
setiap kali teks pencarian berubah.cellForRowAtIndexPath
, bukankah seharusnya Anda mendapatkan selself.tableView
seperti seseorang yang ditunjukkan dalam pertanyaan SO ini ? Jika Anda tidak melakukan ini, sel khusus tidak ditampilkan.Beberapa berkomentar bahwa ini dapat dilakukan dengan satu
NSFetchedResultsController
. Itulah yang saya lakukan, dan inilah detailnya. Solusi ini mengasumsikan Anda hanya ingin memfilter tabel dan mempertahankan semua aspek lainnya (urutan, tata letak sel, dll.) Dari hasil pencarian.Pertama, tentukan dua properti di
UITableViewController
subclass Anda (dengan @synthesize dan dealloc yang sesuai, jika berlaku):Kedua, inisialisasi bilah pencarian dalam
viewDidLoad:
metodeUITableViewController
subclass Anda :Ketiga, terapkan
UISearchDisplayController
metode delegasi seperti ini:Akhirnya, dalam
fetchedResultsController
metode ini ubahNSPredicate
ketergantungan jikaself.searchString
didefinisikan:sumber
Saya perlu beberapa upaya untuk membuatnya berfungsi ...
Kunci pemahaman saya adalah menyadari bahwa ada dua tableViews yang bekerja di sini. Satu dikelola oleh viewcontroller saya dan satu dikelola oleh searchviewcontroller dan kemudian saya bisa menguji untuk melihat mana yang aktif dan melakukan hal yang benar. Dokumentasi juga membantu:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UISearchDisplayController_Class/Reference/Reference.html
Inilah yang saya lakukan -
Menambahkan bendera searchIsActive:
Menambahkan synthesize dalam file implementasi.
Kemudian saya menambahkan metode ini untuk pencarian:
Kemudian di controllerWillChangeContent:
Dan controllerDidChangeContent:
Dan hapus cache saat mengatur ulang predikat.
Semoga ini membantu.
sumber
if ( [self.tableView isEqual:self.searchDisplayController.searchResultsTableView] ) { ... }
Saya dihadapkan dengan tugas yang sama dan menemukan CARA YANG SEDERHANA untuk menyelesaikannya. Singkatnya: Anda perlu mendefinisikan satu metode lagi, sangat mirip
-fetchedResultsController
dengan predikat gabungan khusus.Dalam kasus pribadi saya,
-fetchedResultsController
penampilan saya seperti ini:Seperti yang Anda lihat, saya mengambil klien dari satu agensi yang difilter menurut
agency.server_id
predikat. Akibatnya saya mengambil konten saya ditableView
(semua yang berhubungan dengan implementasitableView
danfetchedResultsController
kode cukup standar) juga. Untuk mengimplementasikansearchField
saya mendefinisikanUISearchBarDelegate
metode delegasi. Saya memicunya dengan metode pencarian, katakan-reloadTableView
:dan tentu saja definisi
-reloadTableView
:Kumpulan kode ini sangat mirip dengan yang pertama, "standar"
-fetchedResultsController
TETAPI pernyataan if-else di sini adalah:+andPredicateWithSubpredicates:
- menggunakan metode ini kita dapat menetapkan predikat untuk menyimpan hasil pengambilan pertama utama kita ditableView
+orPredicateWithSubpredicates
- menggunakan metode ini, kami memfilter pengambilan yang ada dengan permintaan pencarian darisearchBar
Pada akhirnya saya menetapkan array predikat sebagai predikat gabungan untuk pengambilan khusus ini. DAN untuk predikat yang diperlukan, ATAU untuk opsional.
Dan itu saja! Anda tidak perlu menerapkan apa pun lagi. Selamat coding!
sumber
Apakah Anda menggunakan pencarian langsung?
Jika Anda TIDAK, Anda mungkin menginginkan sebuah array (atau NSFetchedResultsController) dengan pencarian sebelumnya yang Anda gunakan, ketika pengguna menekan "search", Anda memberi tahu FetchedResult Anda untuk mengubah predikatnya.
Apa pun itu, Anda harus membangun kembali Hasil Fetched Anda setiap saat. Saya sarankan menggunakan hanya satu NSFetchedResultsController, karena Anda harus menduplikasi kode Anda banyak dan Anda tidak perlu membuang memori dalam sesuatu yang tidak Anda tampilkan.
Pastikan Anda memiliki variabel "searchParameters" NSString dan metode FetchedResults membangunnya kembali untuk Anda sesuai kebutuhan, menggunakan parameter pencarian jika tersedia, Anda harus melakukan:
Ini kode sederhana:
sumber
Swift 3.0, UISearchController, NSFetchedResultsController dan Data Inti
Kode ini akan berfungsi di Swift 3.0 with
Core Data
! Anda akan memerlukan metode delegasi tunggal dan beberapa baris kode untuk memfilter dan mencari objek dari model. Tidak ada yang diperlukan jika Anda telah menerapkan semuaFRC
dandelegate
metode mereka jugasearchController
.The
UISearchResultsUpdating
Metode ProtokolItu dia! Semoga ini bisa membantu Anda! Terima kasih
sumber
SWIFT 3.0
Gunakan textField, UISearchDisplayController sudah usang pada iOS 8, Anda harus menggunakan UISearchController. Alih-alih berurusan dengan Kontroler Pencarian, mengapa Anda tidak membuat mekanisme pencarian Anda sendiri? Anda dapat menyesuaikannya lebih banyak dan memiliki kontrol lebih besar terhadapnya, dan tidak perlu khawatir tentang perubahan SearchController dan / atau tidak digunakan lagi.
Metode ini saya gunakan bekerja dengan sangat baik, dan tidak memerlukan banyak kode. Itu mengharuskan Anda menggunakan Data Inti dan mengimplementasikan NSFetchedResultsController, namun.
Pertama, buat TextField dan daftarkan dengan metode:
Kemudian buat metode textFieldDidChange Anda, dijelaskan dalam pemilih ketika target ditambahkan:
Kemudian Anda ingin memfilter daftar dalam
filterList()
metode menggunakan NSPredicate atau NSCompound predikat jika lebih kompleks. Dalam metode filterList saya, saya memfilter berdasarkan nama entitas, dan nama entitas "subKategori" objek (hubungan satu ke banyak).sumber
Saya pikir Luka memiliki pendekatan yang lebih baik untuk ini. Lihat LargeDataSetSample dan alasannya
Dia tidak menggunakan
FetchedResultsController
, tetapi menggunakan cache saat mencari, karenanya hasil pencarian tampak jauh lebih cepat ketika pengguna mengetik lebih banyak di SearchBarSaya telah menggunakan pendekatannya di aplikasi saya dan berfungsi dengan baik. Ingat juga jika Anda ingin bekerja dengan objek Model, buat sesederhana mungkin, lihat jawaban saya tentang setPropertiesToFetch
sumber
Inilah cara menangani fetchedResult dengan beberapa set data yang sederhana dan cukup umum untuk diterapkan hampir di mana saja. Cukup ambil hasil utama Anda ke array ketika beberapa kondisi hadir.
Permintaan array dengan mengulanginya atau apa pun yang Anda inginkan untuk membuat subset dari hasil utama yang diambil. Dan sekarang Anda dapat menggunakan set lengkap atau subset ketika beberapa kondisi hadir.
sumber
Saya sangat menyukai pendekatan @Josh O'Connor di mana dia tidak menggunakan
UISearchController
. Pengontrol ini masih (Xcode 9) memiliki bug tata letak yang banyak mencoba untuk mengatasinya.Saya kembali menggunakan
UISearchBar
bukanUITextField
, dan itu bekerja dengan cukup baik. Persyaratan saya untuk pencarian / filter adalah untuk menghasilkanNSPredicate
. Ini diteruskan ke FRC:...
Akhirnya, pasang SearchBar ke delegasinya.
Saya harap ini membantu orang lain
sumber
Pendekatan Sederhana untuk Memfilter UITableView yang ada menggunakan CoreData dan yang sudah diurutkan bagaimana Anda inginkan.
Ini benar-benar juga saya 5 menit untuk mengatur dan mulai bekerja.
Saya sudah
UITableView
menggunakan menggunakanCoreData
diisi dengan Data dari iCloud dan yang memiliki interaksi pengguna yang cukup rumit dan saya tidak ingin harus meniru semua itu untukUISearchViewController
. Saya bisa dengan mudah menambahkan predikat ke yangFetchRequest
sudah digunakan olehFetchResultsController
dan yang menyaring data yang sudah diurutkan.sumber