我在SwiftUI中有一个内容视图,它有一个导航链接,可以转到另一个视图CurrenciesView()。
type hereimport SwiftUI
import CoreData
struct ContentView: View {
// @Environment(\.managedObjectContext) private var viewContext
//
// @FetchRequest(
// sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
// animation: .default)
// private var items: FetchedResults<Item>
var body: some View {
NavigationView {
VStack{
Text("Check today's USD currency")
.font(.title)
.fontWeight(.semibold)
.frame(maxWidth: .infinity, alignment: .leading)
NavigationLink {
CurrenciesView()
} label: {
Text("Search for currencies")
}
Divider()
}
.navigationTitle("Rapid Booking")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
}
CurrenciesView():
import SwiftUI
struct CurrenciesView: View {
@StateObject private var vm = CurrenciesViewModel()
var body: some View {
ZStack{
if vm.isLoading{
ProgressView()
}
else{
List{
ForEach((vm.currency?.exchange_rates)!, id: \.currency){ rate in
CurrencyItem(rate: rate.exchange_rate_buy ?? "Unknown", currency: rate.currency ?? "Unknown")
.listRowSeparator(.hidden)
}
}
.listStyle(.plain)
.navigationTitle("\(vm.currency?.base_currency_date ?? "Unknown")'s USD rate")
}
}
.onAppear(perform: vm.fetchCurrency)
.alert(isPresented: $vm.hasError, error: vm.error) {
Button {
vm.fetchCurrency()
} label: {
Text("Cancel")
}
}
}
}
struct CurrenciesView_Previews: PreviewProvider {
static var previews: some View {
CurrenciesView()
}
}
struct CurrencyItem: View{
let rate: String
let currency: String
var body: some View{
VStack(alignment: .leading){
Text("**Currency**: \(currency)")
Divider()
Text("**Rate**: \(rate)")
}
.frame(maxWidth: .infinity,
alignment: .leading)
.padding()
.background(Color.gray.opacity(0.1), in: RoundedRectangle(cornerRadius: 10, style: .continuous))
.padding(.horizontal, 4)
}
}
Currencies视图总是强制在ForEach中展开一个nil值,因为vm没有执行函数来解析来自API的数据。我在onAppear()中设置了它,但它从未被触发。
我在onAppear()上设置了断点,并在模拟器上运行,但它没有进入断点,它不应该先进入断点吗?
1条答案
按热度按时间pu82cl6c1#
将
CurrenciesViewModel
重命名为CurrencyFetcher
,并在类的init
中执行初始提取。@StateObject
在body调用之前是init。onAppear
用于当自动生成的UIView
对象出现时的外部操作,它并不是真正为延迟加载数据而设计的。SwiftUI的设计需要预先准备好的数据,而View
结构层次结构是该状态的函数。