环境:Xcode版本11.0 beta 4(11M374r)
我无法与第二个观点分享“环境”。
我已在SceneDelegate中实例化了环境BindableObject:
我在基础(ContentView)和详细视图中都使用@EnvironmentObject。
该环境已经在SceneDelegate中设置,因此它应可用于所有视图。
ContentView确实看到了环境。
但是DetailView爆炸了:
这是完整的代码:
import Combine
import SwiftUI
struct UserInfo {
var name: String
var message: String
init(name: String, msg: String) {
self.name = name; self.message = msg
}
}
// A BindableObject is always a class; NOT a struct.
class UserSettings: BindableObject {
let willChange = PassthroughSubject<Void, Never>()
var userInfo = UserInfo(name: "Ric", msg: "Mother had a feeling, I might be too appealing.") {
didSet {
willChange.send()
}
}
}
// =====================================================================================================
struct DetailView: View {
@Binding var dismissFlag: Bool
@EnvironmentObject var settings: UserSettings // ...<error source>
var body: some View {
VStack {
Spacer()
Button(action: dismiss) {
Text("Dismiss")
.foregroundColor(.white)
}
.padding()
.background(Color.green)
.cornerRadius(10)
.shadow(radius: 10)
Text("Hello")
Spacer()
}
}
private func dismiss() {
settings.userInfo.message = "Rubber baby buggy bumpers."
dismissFlag = false
}
}
// ---------------------------------------------------------------------------
// Base View:
struct ContentView: View {
@State var shown = false
@EnvironmentObject var settings: UserSettings
var body: some View {
VStack {
Spacer()
Button(action: {
self.settings.userInfo.name = "Troglodyte"
self.settings.userInfo.message = "Top Secret"
self.shown.toggle()
}) {
Text("Present")
.foregroundColor(.white)
}.sheet(isPresented: $shown) { DetailView(dismissFlag: self.$shown) }
.padding()
.background(Color.red)
.cornerRadius(10)
.shadow(radius: 10)
Text(self.settings.userInfo.message)
Spacer()
}
}
}
// =====================================================================================================
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
我想念什么?
我在做什么错了?
import SwiftUI
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var userSettings = UserSettings()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use a UIHostingController as window root view controller
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(userSettings))
self.window = window
window.makeKeyAndVisible()
}
}
}
修改SceneDelegate后出现运行时错误消息:
答案 0 :(得分:1)
在SceneDelegate
中,您需要声明变量的实例:
var userSettings = UserSettings() // <<--- ADD THIS
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: ContentView()
.environmentObject(userSettings) <<-- CHANGE THIS
)
self.window = window
window.makeKeyAndVisible()
}
}
这将创建{/ {1}}的全局/环境实例。
编辑:
发生第二个错误,与将userSettings
暴露给预览有关。对于this answer by @MScottWaller,您需要在@EnvironmentObject
和 SceneDelegate
中创建一个单独的实例。
PreviewProvider