[英]SwiftUI View not updating with binding to computed property on ObservableObject
我有一個非常簡單的SwiftUI視圖,它只顯示一個TextField
。 文本字段的text
綁定到我實例化為viewModel
的@StateObject
的string
屬性:
struct ContentView: View {
@StateObject private var viewModel = ViewModel()
var body: some View {
TextField("Placeholder", text: $viewModel.string)
.padding()
}
}
“與眾不同”的一件事是我的string
屬性不是@Published
屬性,而是一個簡單的計算屬性。 在它的設置器中,它把displayedString
屬性設置為一個固定字符串(用於測試目的),它是一個 @Published 屬性:
class ViewModel: ObservableObject {
@Published var displayedString: String = ""
var string: String {
get { displayedString }
set { displayedString = "OVERRIDE" }
}
}
因此,當我在文本字段中輸入字符串時,我希望 setter 觸發視圖更新(因為它更新了@Published
屬性),然后在displayedString
中,文本字段應該使用 displayString 進行更新。 換句話說:無論我輸入什么,文本字段都應該始終顯示字符串OVERRIDE
。
但事實並非如此!
它適用於我輸入的第一個字母,但隨后我可以在文本字段中自由輸入任何內容。
例如,如果我僅使用此視圖啟動應用程序並鍵入字符串123456789
,這就是文本字段上顯示的內容: OVERRIDE23456789
以及如何使文本字段始終與viewModel
上設置的內容保持同步? (我知道,我可以直接將文本字段連接到@Published
屬性,但我這樣做是有原因的,並且想了解它為什么不能按預期工作。)
當我在TextField
上方添加Text
label 並使其顯示viewModel.string
時,它會顯示正確的(預期的)字符串:
var body: some View {
Text(viewModel.string)
TextField("Placeholder", text: $viewModel.string)
.padding()
}
我不確定,但我認為自定義綁定可能對您有用
在 ViewModel 中使用
var string: Binding<String> { Binding(
get: { displayedString },
set: { displayedString = “OVERRIDE” } )}
然后在正文中使用:viewModel.string 而不是 TextField 中的 $viewModel.string 並在文本視圖中使用:viewModel.string.wrappedValue
東西
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.