- Published on
SwiftUI'da Searchable, Scopes va Suggestions
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
Qidiruv panelini yaratish: .searchable
Ilgari SwiftUI'da qidiruv qatorini (Search Bar) noldan o'zimiz yasashimizga to'g'ri kelardi. iOS 15 va ayniqsa iOS 16 dan boshlab, Apple bizga mukammal aylanib ishlaydigan tayyor animatsiyali qidiruv oynasini bitta qator kod orqali qo'shish imkonini berdi.
Buning uchun Ro'yxatimizga (List, ScrollView) shunchaki .searchable modifierini qo'shib, uni bitta o'zgaruvchiga bog'lashimiz (Bind qilish) kifoya:
struct RestaurantView: View {
@StateObject private var vm = RestaurantViewModel()
var body: some View {
NavigationStack {
List(vm.filteredRestaurants) { restaurant in
Text(restaurant.title)
}
.navigationTitle("Restoranlar")
// 💡 Mana shu bir qator kod butunlay tayyor Search Bar yaratadi!
.searchable(text: $vm.searchText, prompt: "Restoran qidiring...")
}
}
}
MVVM'da qidiruv mantig'i (Debounce texnikasi)
ViewModel ichida foydalanuvchi qidirayotganda qanday ishlashini ko'rib chiqamiz. Asosiy qoida shuki, Asl ma'lumotlar massivi va filtrlangan ma'lumotlar massivi har doim alohida bo'lishi shart!
Shuningdek, foydalanuvchi har bir harfni yozganda (masalan, "B-u-r-g-e-r") dastur tinimsiz hisob-kitob qilib qotib qolmasligi uchun, u yozib bo'lguncha (masalan 0.3 soniya) kutib turish – Debounce texnikasidan foydalanamiz. Combine freymvorki yordamida buni osongina qilamiz:
@MainActor
class RestaurantViewModel: ObservableObject {
@Published var searchText: String = ""
@Published var allRestaurants: [Restaurant] = [] // Asl ma'lumot
@Published var filteredRestaurants: [Restaurant] = [] // Ekranda chiqadigani
private var cancellables = Set<AnyCancellable>()
init() {
// ... ma'lumotlarni yuklash ...
addSubscribers()
}
private func addSubscribers() {
$searchText
.debounce(for: 0.3, scheduler: DispatchQueue.main) // 0.3 soniya kutish
.sink { [weak self] returnedText in
self?.filterRestaurants(text: returnedText)
}
.store(in: &cancellables)
}
private func filterRestaurants(text: String) {
guard !text.isEmpty else {
filteredRestaurants = allRestaurants
return
}
filteredRestaurants = allRestaurants.filter { restaurant in
restaurant.title.lowercased().contains(text.lowercased())
}
}
}
Kategoriyalar bo'yicha qidiruv: .searchScopes
Ba'zan foydalanuvchi ma'lumotlarni faqat ma'lum bir toifa (Kategoriya) bo'yicha qidirishni xohlaydi. Masalan, barcha restoranlar orasidan faqat "Italiya taomlari" yo'nalishidagilarini qidirish.
Apple buning uchun tayyor .searchScopes xususiyatini taqdim qildi. U qidiruv qatori ostida chiroyli toifalar menyusini ko'rsatadi:
enum SearchScope {
case all, american, italian, japanese
}
// View'da:
.searchScopes($vm.currentScope) {
Text("Barchasi").tag(SearchScope.all)
Text("Amerika").tag(SearchScope.american)
Text("Italiya").tag(SearchScope.italian)
Text("Yaponiya").tag(SearchScope.japanese)
}
Endi ViewModel'dagi filterRestaurants funksiyamiz ichida nafaqat yozuvni (searchText), balki tanlangan toifani (currentScope) ham hisobga olib filtrlashimiz kerak bo'ladi!
Qidiruv tavsiyalari: .searchSuggestions
Eng zo'r dasturlar qidiruv paneliga yozishni boshlashingiz bilanoq sizga tezkor variantlarni (Tavsiyalarni) taklif qiladi. Buni amalga oshirish uchun .searchSuggestions modifieridan foydalanamiz.
.searchSuggestions {
Text("Burger Shack").searchCompletion("Burger Shack")
Text("Sushi Heaven").searchCompletion("Sushi Heaven")
}
searchCompletion nima qiladi? Ushbu tavsiya etilgan so'zlardan birortasini foydalanuvchi bosa, yozuv avtomatik tarzda Qidiruv qatoriga yoziladi (kiritiladi) va dastur uni xuddi siz to'liq terib yozganingizdek qabul qilib, qidiruvni boshlaydi.
Xulosa
Searchable ekotizimi bilan biz:
searchable- chiroyli qidiruv qatori yaratdik.searchScopes- kategoriyalar bo'yicha izlashni osonlashtirdik.searchSuggestions- aqlli takliflar tizimini joriy qildik.
Agar bu modifikatorlardan birgalikda foydalansangiz, sizning ilovangizdagi qidiruv tajribasi (UX) xuddi Apple ning o'zining professional ilovalari darajasida bo'ladi!