gpt4 book ai didi

SwiftUI : possible to access ancestor custom `@EnvironmentObject` ? 如果是,怎么办?

转载 作者:行者123 更新时间:2023-11-28 13:29:14 24 4
gpt4 key购买 nike

(使用 Xcode 11 beta 7)是否可以访问祖先的自定义 EnvironmentObject?如果是这样怎么办?并使用无限深度?

假设我们的导航有很多层次,例如

UIScene -> MainView -> TabView(其中包含一个选项卡:) -> SettingsView -> AboutView -> AppVersionView

开始将 MainView 计为深度级别 1,而不是计算 TabView,我们的 AppVersionView 在我们的导航堆栈中处于深度级别 4。

假设我们需要使用一些自定义依赖项,例如RESTClient 或 AppVersionView 中的任何内容。这种依赖是什么是无关紧要的。相关的是,我们的 SceneDelegate 类实例化了这种依赖关系,深度 1 (MainView) 的 View 将其声明为 @EnvirontmentObject 以将其注入(inject)。

我当前的解决方案是 MainView 通过将其向下注入(inject)到堆栈中的下一个 View SettingsView 来“手动”转发它。在 SettingsView 中,我再次手动转发它等。

这是一个简化的示例,实际上我在整个 my SwiftUI app 中都有多个依赖项,在整个导航堆栈中被使用和不同的层。

我的想法是,是否有可能以某种方式读取/访问这些注入(inject)的 EnvironmentObjects?在最好的情况下,从任何较早的祖先递归。

如果我没有正确理解 SwiftUI,那么 ViewModifier 就是这种情况。如果我将 ViewModifier .foregroundColor(.red) 添加到 MainView,它应该作为系统范围的默认颜色通过应用程序(继承)传递。

我希望可以使用自定义 EnvironmentObject 来完成同样的事情。我知道我们可以访问预定义(非自定义)EnvironmentValues , 在我们看来像 this example from Mecid's great blog:

struct ButtonsView: View {
@Environment(\.sizeCategory) var sizeCategory

var body: some View {
Group {
if sizeCategory == .accessibilityExtraExtraExtraLarge {
VStack {
buttons
}
} else {
HStack {
buttons
}
}
}
}

最佳答案

使用 environmentObject 修饰符放入环境中的对象通过 TabViewNavigationView 传递到 View 层次结构中的所有后代 View .您无需执行任何特殊操作(如手动转发)即可实现此目的。

在此示例中,在 SceneDelegate 中,我将使用 environmentObject 修饰符将模型对象存储在 MainView 的环境中。模型对象有一个 appVersion 字符串属性。我将使用 AppVersionView 中的 @EnvironmentObject 属性访问模型对象,并使用模型的 appVersion 填充 Text subview 。

enter image description here

代码如下:

import UIKit
import SwiftUI

class Model: ObservableObject {
@Published var appVersion: String = "version-1"
}

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else { return }

let model = Model()
let contentView = MainView().environmentObject(model)
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}

struct MainView: View {
var body: some View {
TabView {
NavigationView {
SettingsView()
}
.tabItem {
Image(systemName: "gear")
Text("Settings") }
}
}
}

struct SettingsView: View {
var body: some View {
List {
NavigationLink("About", destination: AboutView())
}
}
}

struct AboutView: View {
var body: some View {
List {
NavigationLink("App Version", destination: AppVersionView())
}
}
}

struct AppVersionView: View {
@EnvironmentObject var model: Model

var body: some View {
VStack {
Text("App Version View")
Text(model.appVersion)
}
.padding()
.border(Color.black)
}
}

关于SwiftUI : possible to access ancestor custom `@EnvironmentObject` ? 如果是,怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57717368/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com