英文:
SwiftUI searchable in Model()
问题
I've translated the content you provided, focusing on the code parts as you requested. Here's the translated code:
我在使用SwiftUI的Searchable时遇到问题,用于我的数据模型。我从Firestore读取了数据,并保存为GBplayerModel()中的数组。
使用Searchable时,它可以过滤球员列表,但在移除搜索文本时不会返回原始列表视图。
基本上,我希望主视图是可以搜索的完整列表。
数据模型
import Foundation
import Firebase
struct GBplayer: Identifiable {
var id: String
var name: String
var status: String
var height: String
var team: String
var position: String
}
// 用于预览的模拟数据
extension GBplayer {
static func mock() -> GBplayer {
GBplayer(id: "Aaron Menzies", name: "Aaron Menzies", status: "Active", height: "7ft 3", team: "Leicester Riders", position: "C")
}
}
class GBplayerModel: ObservableObject {
@Published var playerList = [GBplayer]()
func getGBplayers() {
// 获取数据库引用
let db = Firestore.firestore()
db.collection("GBplayers").getDocuments { snapshot, error in
// 检查错误
if error == nil {
// 没有错误
print("您已登录")
if let snapshot = snapshot {
// 在主线程中更新列表属性
DispatchQueue.main.async {
// 获取所有文档并创建球员列表
self.playerList = snapshot.documents.map { d in
// 为文档中的每个球员创建一个球员结构
return GBplayer(id: d.documentID,
name: d["name"] as? String ?? "",
status: d["status"] as? String ?? "",
height: d["height"] as? String ?? "",
team: d["team"] as? String ?? "",
position: d["position"] as? String ?? "")
}
}
}
} else {
// 处理错误
print("没有文档")
return
}
}
}
}
视图
import SwiftUI
struct playerView: View {
@ObservedObject var model = GBplayerModel()
@State private var searchPlayer = ""
var body: some View {
NavigationView {
List {
ForEach (model.playerList) { player in
NavigationLink {
Text("详细视图") // 需要在此处添加详细视图
} label: {
PlayerRow(player: player)
}
}
}
.listStyle(.plain)
.navigationTitle("球员")
// 从Firebase更新数据
.onAppear() {
self.model.getGBplayers()
}
.searchable(text: $searchPlayer, placement: .navigationBarDrawer(displayMode: .always), prompt: "查找球员")
.onChange(of: searchPlayer) { search in
if !search.isEmpty {model.playerList = model.playerList.filter { $0.name.contains(searchPlayer) }
} else {
model.playerList = model.playerList
}
}
}
}
}
I hope this helps! If you have any further questions or need assistance with specific parts of the code, feel free to ask.
英文:
I am having issues using searchable in SwiftUI for my data model. I have read the data from firestore and saved as an array in GBplayerModel().
When using searchable it filters the list of players but won't go back to the original list view when the search text is removed.
Essentially I want to main view be the full list that can be searched through.
Data Model
import Foundation
import Firebase
struct GBplayer: Identifiable {
var id: String
var name: String
var status: String
var height: String
var team: String
var position: String
}
// mock data that we can use for previews
extension GBplayer {
static func mock() -> GBplayer {
GBplayer(id: "Aaron Menzies", name: "Aaron Menzies", status: "Active", height: "7ft 3", team: "Leicester Riders", position: "C")
}
}
class GBplayerModel: ObservableObject {
@Published var playerList = [GBplayer]()
func getGBplayers() {
// get reference to the db
let db = Firestore.firestore()
db.collection("GBplayers").getDocuments { snapshot, error in
//check for errors
if error == nil {
// no errors
print("your in")
if let snapshot = snapshot {
// Update the list property in the main thread
DispatchQueue.main.async {
// get all the documents and create list of players
self.playerList = snapshot.documents.map { d in
//create a player struc for each player in the document
return GBplayer(id: d.documentID,
name: d["name"] as? String ?? "",
status: d["status"] as? String ?? "",
height: d["height"] as? String ?? "",
team: d["team"] as? String ?? "",
position: d["position"] as? String ?? "",
}
}
}
} else {
// handle the error
print("No Documents")
return
}
}
}
}
View
import SwiftUI
struct playerView: View {
@ObservedObject var model = GBplayerModel()
@State private var searchPlayer = ""
var body: some View {
NavigationView {
List {
ForEach (model.playerList) { player in
NavigationLink {
Text("Detailed View") //need to add detailed view here
} label: {
PlayerRow(player: player)
}
}
}
.listStyle(.plain)
.navigationTitle("Players")
// update data from Firebase
.onAppear() {
self.model.getGBplayers()
}
.searchable(text: $searchPlayer, placement: .navigationBarDrawer(displayMode: .always), prompt: "Find a player")
.onChange(of: searchPlayer) { search in
if !search.isEmpty {model.playerList = model.playerList.filter { $0.name.contains(searchPlayer) }
} else {
model.playerList = model.playerList
}
}
}
}
}
Any help would be greatly appreciated, spent a lot time of this and appreciate it maybe something simple
答案1
得分: 1
现在,当您搜索时,您正在改变您的 playerList
,当您执行以下操作时:
model.playerList = model.playerList.filter { ... }
这意味着如果您更改搜索词(或者将其删除),那些被过滤掉的项目将不再存在。
相反,您应该始终保留完整的 playerList
,并且只 显示 一个经过筛选的版本:
var filteredList: [GBplayer] {
if search.isEmpty {
return model.playerList
} else {
return model.playerList.filter { ... }
}
}
// ...
ForEach(filteredList) { player in ... }
然后删除您的 onChange
代码。
英文:
Right now, when you search, you're mutating your playerList
when you do this:
model.playerList = model.playerList.filter { ... }
That means that if you change your search term (or get rid of it), the items that were filtered out no longer exist.
Instead, you should always keep the full playerList
and only display a filtered version:
var filteredList: [GBplayer] {
if search.isEmpty {
return model.playerList
} else {
return model.playerList.filter { ... }
}
}
// ...
ForEach (filteredList) { player in ... }
And remove your onChange
code
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论