在NavigationView中加载视图的标准方式是什么(每个视图都拥有从API填充的模型)?

时间:2020-10-16 13:35:01

标签: swiftui swiftui-navigationlink

我有2个视图:A和B。视图A具有一个模型,该模型可从API端点加载其数据,而视图B则相同。

视图A有一个按钮,单击该按钮会将视图B推入堆栈。这是执行此操作的代码:

应用程序:

import SwiftUI

@main
struct TempApp: App {
    var body: some Scene {
        WindowGroup {
            ViewA()
        }
    }
}

视图/模型A:

import SwiftUI

let REQUEST_DELAY = 6.0 // to simulate(ish) a network request

struct ViewA: View {
    @ObservedObject var model: ViewAModel = ViewAModel()
    @State var shouldGoToNextView = false
    
    var body: some View {
        NavigationView {
            if (self.model.isLoaded) {
                VStack {
                    Text(self.model.data)
                        .font(.title)
                    NavigationLink(destination: ViewB(), isActive:$shouldGoToNextView) {
                        EmptyView()
                    }
                    Button(action: {self.shouldGoToNextView=true}) {
                        Text("GO")
                            .font(.headline)
                            .foregroundColor(.white)
                            .padding()
                            .frame(width: 220, height: 60)
                            .background(Color.blue)
                            .cornerRadius(15.0)
                    }
                }
            } else {
                Text("Not ready...")
                    .font(.title)
            }
        }
        .onAppear(perform: {
            self.shouldGoToNextView = false
        })
    }
}

class ViewAModel : ObservableObject {
    var data: String = ""
    @Published var isLoaded : Bool = false
    
    init() {
        // simulate getting the data from the network
        DispatchQueue.main.asyncAfter(deadline: .now() + REQUEST_DELAY) {
            // your code here
            self.data = "All loaded fine.."
            self.isLoaded = true
        }
    }
}

struct ViewA_Previews: PreviewProvider {
    static var previews: some View {
        ViewA()
    }
}

模型/视图B:

import SwiftUI

struct ViewB: View {
    @ObservedObject var model: ViewBModel = ViewBModel()
    var body: some View {
        if (self.model.isLoaded) {
            Text(self.model.data)
                .font(.title)
        } else {
            Text("Secondary data not ready...")
                .font(.title)
        }
    }
}

class ViewBModel: ObservableObject {
    var data: String = ""
    @Published var isLoaded: Bool = false
    
    init() {
        // simulate getting the data from the network
        DispatchQueue.main.asyncAfter(deadline: .now() + REQUEST_DELAY) {
            self.data = "Secondary model data loaded fine.."
            self.isLoaded = true
        }
    }
}

struct ViewB_Previews: PreviewProvider {
    static var previews: some View {
        ViewB()
    }
}

此代码在运行时有效,但我有1个问题和1个问题:

问题:这是在SwiftUI中实现上述目标的最佳方法吗?具体来说,我不确定使用State / ObservedObject以及NavigationLink和Button组合导航到另一个视图。

问题:我无法在正在使用的真实应用中预览View A,因为View A的代码会立即实例化View B(在NavigationLink调用中),因此Model B进行了网络调用来加载它的数据,并导致错误:

更新花费了5秒钟以上

即使我延迟加载数据,上面的示例应用程序也可以很好地预览,所以我不确定为什么!

1 个答案:

答案 0 :(得分:1)

1-要查看视图B,使用此代码会容易得多:

np.mean(X[Y==c]

2-应该使用 NavigationLink(destination: ViewB()) { Text("Your buttons text") } 而不是使用ObservedObject

3-使用StateObject的方式,您只需@发布您的isLoaded

4-为了能够预览它们,我建议您将它们包装在一个容器视图中,您可以在其中传递其依赖性,在本例中为data,它是一个字符串。例如:

data