[英]Why does SwiftUI not update a view here?
当 isConnected 更新时,下方 ReadyDashboardView 中的背景颜色和文本不会更新。 显然,我想在建立连接时更新视图。 我期待将链中的所有内容发布到该变量会使其在 swiftui 中立即更新。 相反,它总是使用实例化变量时提供的值进行渲染。 这是一个非常简化的情况:
我应该使用另一个 swiftui 功能还是我必须对我的代码库进行一些彻底的更改?
import SwiftUI
@main
struct TestApp: App {
@StateObject private var env = PrinterEnv()
var body: some Scene {
WindowGroup {
ReadyDashboardView()
.environmentObject(env)
}
}
}
struct ReadyDashboardView: View {
@EnvironmentObject var env: PrinterEnv
var body: some View {
VStack {
HStack {
Spacer()
VStack {
Text(env.selectedPrinter?.isConnected ?? false ? "Printer Ready" : "Not Connected")
.padding(.bottom)
}
Spacer()
}
.background(env.selectedPrinter?.isConnected ?? false ? .green : .red)
Button("Connect") { env.selectedPrinter?.isConnected = true }
Button("Disconnect") { env.selectedPrinter?.isConnected = false }
}
}
}
class PrinterEnv: ObservableObject {
@Published var configuredPrinters: [Printer] = []
@Published var selectedPrinter: Printer?
init() {
configuredPrinters.append(contentsOf: [Printer()])
selectedPrinter = configuredPrinters.first
}
}
class Printer: ObservableObject {
@Published var isConnected = false
}
我建议你不要嵌套ObservableObject
,它不能很好地工作。
例如,尝试使用Printer
结构,例如:
struct Printer: Identifiable {
let id = UUID()
var isConnected = false
}
我不认为这个问题与嵌套的可观察对象特别相关。 嵌套它们运行良好,甚至被社区成员推荐为管理应用程序范围状态并确保性能可接受的最佳方式。
看到这个: https://www.fivestars.blog/articles/app-state/
也就是说,我相信它可能与使用@Published
属性包装器包装可观察的 object 有关。
在操场上试试这个:
import SwiftUI
class AppState: ObservableObject {
let fooState = FooState()
let barState = BarState()
}
class FooState: ObservableObject {
@Published var foo: Int = 42
}
class BarState: ObservableObject {
@Published var bar: String = Date().debugDescription
}
struct FooView: View {
@EnvironmentObject var fooState: FooState
var body: some View {
Text("foo: \(fooState.foo)")
}
}
struct BarView: View {
@EnvironmentObject var barState: BarState
var body: some View {
Text("bar: \(barState.bar)")
}
}
struct ContentView: View {
@EnvironmentObject var appState: AppState
var body: some View {
VStack {
Spacer()
FooView()
.environmentObject(appState.fooState)
Button("update foo") {
appState.fooState.foo = Int.random(in: 1...100)
}
Spacer()
BarView()
.environmentObject(appState.barState)
Button("update bar") {
appState.barState.bar = Date().debugDescription
}
Spacer()
}
}
}
import PlaygroundSupport
PlaygroundPage.current.liveView = UIHostingController(
rootView: ContentView()
.frame(width: 320, height: 414)
.environmentObject(AppState())
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.