我是SwiftUI的新手,试图从本地保存的JSON文件加载列表。我可以显示json列表,但我想将其滚动到列表中的特定索引。以下是我在View中的代码:
struct SignUpEnterPhoneNumberView: View {
@StateObject private var presenter = CountryListPresenter()
@State private var searchText = ""
var body: some View {
VStack {
NavigationStack {
ScrollView {
ScrollViewReader { proxy in
ForEach(presenter.countries, id: \.self) { country in
HStack(spacing: 10) {
Text(country.emoji ?? "")
Text(country.phone)
Text(country.name)
Spacer()
}
}
.onChange(of: presenter.countries.count, perform: { _ in
proxy.scrollTo(30)
})
}
}
.navigationBarTitle(Text("Select Country Code"), displayMode: .inline)
Spacer()
}
.searchable(text: $searchText, prompt: presenter.searchTitle)
}
}
}
我的演示者文件:
class CountryListPresenter: ObservableObject {
let navigationTitle: String
let searchTitle: String
var countries = [CountryInfoValue]()
var selectedIndex = 50
init(
) {
navigationTitle = "Select Country Code"
searchTitle = "Search"
fetchCountryList()
}
func fetchCountryList() {
guard let url = Bundle.main.url(forResource: "countries.emoji", withExtension: "json") else {
return
}
let data = try? Data(contentsOf: url)
if let data = data {
let countryInfo = try? JSONDecoder().decode(CountryInfo.self, from: data)
var countryList = countryInfo?.map { $0.value }
countryList = countryList?.sorted(by: { $0.name < $1.name })
guard let countryList = countryList else {
return
}
countries = countryList
}
}
}
我试过onAppear和onChange,但都不管用。
2条答案
按热度按时间mctunoxg1#
尝试这种方法,在
ScrollView
之外使用ScrollViewReader
,在ScrollView
之外使用.onChange(...)
,如示例代码所示。正如我在评论中所说的,在
class CountryListPresenter: ObservableObject
中使用@Published var countries = [CountryInfoValue]()
。另请注意,声明struct CountryInfoValue: Identifiable
,不要在ForEach循环中使用,id: \.self
。下面的例子适用于我:
编辑-1:
您可以轻松地使用
.onAppear{...}
而不是Button
的...scroll to a row on view load
。下面是对我有用的代码:wlzqhblo2#
请尝试将此声明为
如果你想监听ObservableObject类的字段的变化,你应该声明它们@Published,这样当它的值改变时,它们就可以更新监听器。
我相信,因为它没有公布其空状态是复制到国家。你不能滚动到项目,因为它是空的。
下面的代码按预期工作。我试图复制你的逻辑。