struct Test: View {
@ObservedObject var datas2 = ReadData2()
@State var selectedIndex2 = 0
var body: some View {
VStack{
List{
HStack{
Text("From")
.foregroundColor(Color("Color"))
.fontWeight(.bold)
.font(.system(size: 20))
.padding(.leading, 10.0)
.frame(width: nil, height: nil, alignment: .leading)
Picker(selection: $selectedIndex2, label: Text("")) {
ForEach(0 ..< datas2.cities.count, id: .self) {
Text(datas2.cities[$0].name)
}
}.foregroundColor(Color("Color"))
.padding(.trailing)
}
}
}
}
struct City: Codable, Identifiable {
enum CodingKeys: CodingKey {
case name
}
var id = UUID()
var name: String
}
class ReadData2: ObservableObject {
@Published var cities = [City]()
init(){
loadData()
}
func loadData() {
guard let url = Bundle.main.url(forResource: "cities", withExtension: "json")
else {
print("Json file not found")
return
}
let data = try? Data(contentsOf: url)
let cities = try? JSONDecoder().decode([City].self, from: data!)
self.cities = cities!
}
}
我有一个名为cities的json文件,它是这样的:
{
"country": "AD",
"name": "Sant Julià de Lòria",
"lat": "42.46372",
"lng": "1.49129"
},
{
"country": "AD",
"name": "Pas de la Casa",
"lat": "42.54277",
"lng": "1.73361"
},
{
"country": "AD",
"name": "Ordino",
"lat": "42.55623",
"lng": "1.53319"
},
{
"country": "AD",
"name": "les Escaldes",
"lat": "42.50729",
"lng": "1.53414"
},
{
"country": "AD",
"name": "la Massana",
"lat": "42.54499",
"lng": "1.51483"
},
我的问题是引用的数据太多了,一旦我按下选择器,读取数据和在选择器中发布数据需要很长时间,有更好的方法让它更快吗
我正试图通过搜索文本来搜索城市的第一个字母,但它不起作用!我希望你能帮助我!
由于项目数量很大,我建议使用为此优化的List
或LazyVStack
,而不是Picker
。类似于下面的示例代码。注意,您必须根据自己的目的调整UI。
struct ContentView: View {
var body: some View {
Test()
}
}
struct Test: View {
@StateObject var datas2 = ReadData2()
@State var selectedCity: City?
@State private var searchQuery: String = ""
var body: some View {
VStack (spacing: 20) {
TextField("city search", text: $searchQuery).padding(5)
.overlay(RoundedRectangle(cornerRadius: 15).stroke(Color.blue, lineWidth: 1))
.foregroundColor(.blue)
.frame(width: 160)
.padding(.top, 20.0)
HStack {
Text("From")
.fontWeight(.bold)
.font(.system(size: 20))
.padding(.leading, 10.0)
Spacer()
ScrollView {
LazyVStack {
ForEach(datas2.cities.filter{searchFor($0.name)}.sorted(by: { $0.name < $1.name })) { city in
Text(city.name).foregroundColor(selectedCity == city ? .red : .blue)
.onTapGesture {
selectedCity = city
}
}
}
}.frame(width: 222, height: 111)
}
Spacer()
}
}
private func searchFor(_ txt: String) -> Bool {
return (txt.lowercased(with: .current).hasPrefix(searchQuery.trimmingCharacters(in: .whitespacesAndNewlines).lowercased(with: .current)) || searchQuery.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
}
}
struct City: Codable, Identifiable, Hashable {
enum CodingKeys: CodingKey {
case name
}
var id = UUID()
var name: String
}
class ReadData2: ObservableObject {
@Published var cities = [City]()
init() {
loadData()
}
func loadData() {
if let url = Bundle.main.url(forResource: "cities", withExtension: "json") {
do {
let data = try Data(contentsOf: url)
cities = try JSONDecoder().decode([City].self, from: data)
} catch {
print(" error:(error)")
}
}
}
}