为什么把属性改成 @Published会导致SwiftUI无法触发UI更新?
在我正在开发的一个应用中,我添加了一个TextEditor字段,用来显示应用文档的模型对象中 @Published Text属性的内容。
以下是模型对象的相关部分:
final class DrawingInfo: ObservableObject, Codable {
// Items saved with Codable
@Published var title: String
@Published var text: String
@Published var toggleIsOn: Bool = false
let imageSize: CGSize
@Published var backgroundColor = Color.white
@Published var texAspect: Float = 1.0
@Published var linePlacement: Float = 0
// ...
}
ContentView看起来是这样的:
var body: some View {
VStack {
VStack {
DrawingView(drawingInfo: $drawingInfo)
.frame(width: DrawingInfo.defaultSize.width, height: DrawingInfo.defaultSize.height)
.border(Color.blue, width: 4)
.aspectRatio(drawingInfo.imageSize, contentMode: .fit)
TextEditor(text: $drawingInfo.text)
.frame(maxHeight: 50)
HStack {
Button("Test") {
drawingInfo.text += " Extra words."
}
Toggle(isOn: $drawingInfo.toggleIsOn) {
Text("Toggle is on")
}
.frame(maxWidth: 200, alignment: toggleAlignment)
Slider(value: $drawingInfo.linePlacement, in: -1...1) {
}
.frame(maxWidth: 200)
}
}
}
}
}
当你点击“Test”按钮时,它会把字符串“ Extra Words.”追加到模型的text属性中。
然而,我的TextEditor在你对模型的某个 @Published属性再次进行修改之前(例如点击Toggle或调整滑块),不会更新来反映这些更改。
我猜这是因为按钮的闭包直接修改了 text 属性,而不是通过模型的绑定进行修改。
我该如何修改按钮的闭包,使我的TextEditor能够捕捉到 text 属性的变化?是否需要设置一个Combine发布者来触发一个变化?
你可以在Github上查看该项目,链接如下:https://github.com/DuncanMC/DrawingApp.git
解决方案
我给这个问题点了踩,因为你的代码在这里不完整,无法令人满意地回答你的问题;需要去Github才能看到代码。
话虽如此,我看了Github,发现其实不需要把 DrawingInfo 传入到 ContentView。相反,如果你打算在 ContentView 中实例化它,就把 drawingInfo @ObservableObject 写成你需要的形式,或者把它设为 @EnvironmentObject,并通过 .environment 修饰符传递给 ContentView,以便在各处使用同一个实例。
备选方案
以下是一个自包含的代码示例:
final class DrawingInfo: ObservableObject {
@Published var title: String
@Published var text: String
@Published var toggleIsOn: Bool = false
let imageSize: CGSize
@Published var backgroundColor = Color.white
@Published var texAspect: Float = 1.0
@Published var linePlacement: Float = 0
init(title: String, text: String, toggleIsOn: Bool, imageSize: CGSize, backgroundColor: Color = Color.white, texAspect: Float, linePlacement: Float) {
self.title = title
self.text = text
self.toggleIsOn = toggleIsOn
self.imageSize = imageSize
self.backgroundColor = backgroundColor
self.texAspect = texAspect
self.linePlacement = linePlacement
}
}
struct ContentView: View {
@ObservedObject var drawingInfo = DrawingInfo(title: "title", text: "text", toggleIsOn: false, imageSize: CGSize(width: 300, height: 300), texAspect: 10, linePlacement: 10)
@State var toggleAlignment: Alignment = .center
var body: some View {
VStack {
TextEditor(text: $drawingInfo.text)
.frame(maxHeight: 50)
HStack {
Button("Test") {
drawingInfo.text += " Extra words."
}
Toggle(isOn: $drawingInfo.toggleIsOn) {
Text("Toggle is on")
}
.frame(maxWidth: 200, alignment: toggleAlignment)
Slider(value: $drawingInfo.linePlacement, in: -1...1) {
}
.frame(maxWidth: 200)
}
}
}
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。