swift 为什么onAppear没有执行?

x8diyxa7  于 2023-04-28  发布在  Swift
关注(0)|答案(1)|浏览(136)

我在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()上设置了断点,并在模拟器上运行,但它没有进入断点,它不应该先进入断点吗?

pu82cl6c

pu82cl6c1#

CurrenciesViewModel重命名为CurrencyFetcher,并在类的init中执行初始提取。@StateObject在body调用之前是init。onAppear用于当自动生成的UIView对象出现时的外部操作,它并不是真正为延迟加载数据而设计的。SwiftUI的设计需要预先准备好的数据,而View结构层次结构是该状态的函数。

相关问题