代码之家  ›  专栏  ›  技术社区  ›  Sky

SwiftUI使用第二个视图更新第一个视图的列表

  •  0
  • Sky  · 技术社区  · 5 年前

    我的第一个视图可以从API请求中获取所有数据,然后打开第二个视图更改API请求数据,结果崩溃了。

    以下是错误

    Fatal error: No ObservableObject of type NetworkManager found.
    A View.environmentObject(_:) for NetworkManager may be missing as an ancestor of this view.: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/Monoceros_Sim/Monoceros-39.3/Core/EnvironmentObject.swift, line 55
    2019-11-07 12:00:01.961425-0800 EarthQuake[73703:5913116] Fatal error: No ObservableObject of type NetworkManager found.
    A View.environmentObject(_:) for NetworkManager may be missing as an ancestor of this view.: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/Monoceros_Sim/Monoceros-39.3/Core/EnvironmentObject.swift, line 55
    

    import Foundation
    import Combine
    
    final class NetworkManager: ObservableObject {
    
        @Published var posts = [Post]()
    
    
        func fetchData() {
    
             //some code to fetch data, then save to posts
    
        }
    
    }
    

    在我的第一个列表视图文件中:地震学家斯威夫特

    
    import SwiftUI
    
    struct EarthQuakeList: View {
    
        @EnvironmentObject var networkManager: NetworkManager
    
        //@ObservedObject var networkManager = NetworkManager()
    
        var body: some View {
    
            NavigationView {
                List(networkManager.posts) { post in
                    NavigationLink(destination: EarthQuakeDetail(detail: post.properties, location: post.locationCoordinate)) {
                        ListRow(magnitude: post.properties.mag ?? 0.0, place: post.properties.place)
    
                    }
    
                }
              .navigationBarTitle(Text("Today"))      
                .navigationBarItems(
    
                        trailing:
                        VStack {
    
                            Button(action: {
                                print("Edit button tapped")
                                self.showEditPage.toggle()
                            }) {
                                //Top right icon
                                Image(systemName: "pencil.circle")
                                    .resizable()
                                    .frame(width: 20, height: 20, alignment: .center)
                            }.sheet(isPresented: $showEditPage) { 
                                return EditPage().environmentObject(self.networkManager)
    
                            }
    
                        }
    
    
    
    
                )
    
    
    
            }
            .onAppear {
                //Call function to fetch data
                self.networkManager.fetchData()
            }
        }
    }
    

    在我的第二个编辑视图文件中:编辑页.swift

    import SwiftUI
    
    struct EditPage: View {
    
        //@ObservedObject var networkManager = NetworkManager()
    
        @EnvironmentObject var networkManager: NetworkManager
    
        var body: some View {
    
            VStack {
                Text("Edite")
    
    
            }
            .onAppear(){
    
                //I called the same function to get data as in first view file, but it is not updating the list view 
                self.networkManager.fetchData()
    
    
            }
    
        }
    }
    

    斯内德雷特。斯威夫特

    import UIKit
    import SwiftUI
    
    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
        var window: UIWindow?
    
    
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    
            //Set up environment object
            let contentView = EarthQuakeList().environmentObject(NetworkManager())
    
            // Use a UIHostingController as window root view controller.
            if let windowScene = scene as? UIWindowScene {
                let window = UIWindow(windowScene: windowScene)
                window.rootViewController = UIHostingController(
                    rootView: contentView
                )
                self.window = window
                window.makeKeyAndVisible()
            }
        }
    

    所以我希望第二个视图文件调用函数 要从API调用中获取数据,请更新第一个swift文件中的列表视图 ,问题是我只是得到正确的数据回来,视图没有更新新的数据

    0 回复  |  直到 5 年前
        1
  •  27
  •   Sky    5 年前

    整个问题很容易解决只要加上self.networkManager@

    .sheet(isPresented: $showEditPage) { 
                                return EditPage().environmentObject(self.networkManager)
    

    我从文章中得到了原因和灵感: https://github.com/peterfriese/Swift-EnvironmentObject-Demo

        2
  •  2
  •   herzi    5 年前

    NetworkManager 在你的代码里。

    如果您将此行添加到 网络管理器 :

    final class NetworkManager: … {
    
        static let shared = NetworkManager()
    
    }
    

    struct EarthQuakeList: … {
    
        @ObservedObject var networkManager = NetworkManager.shared
    
        …
    
    }
    
    struct EditPage: … {
    
        @ObservedObject var networkManager = NetworkManager.shared
    
        …
    
    }
    

    一旦这一点奏效,我建议大家一起玩 .environmentObject() example )在同一个服务中共享这些类型的应用程序。

        3
  •  2
  •   jamal zare    4 年前

    如果使用sheet-ore导航,则必须传递环境对象,可能是swiftUI的错误,但在Xcode 11.5中对我有效:

    .sheet(isPresented: $show){
            mySheetView().environmentObject(self.myEnviromentObject)
    }