[英]Swift UI not redrawing NSViewRepresentable wrapped textfield
我創建了一個這樣的列表詳細視圖。 在詳細視圖中,有一些接受文本的輸入字段。 輸入字段是使用NSViewRepresentable
包裝的NSTextField
。 問題發生在以下場景中。
首先,單擊一行和 select 人 A。然后嘗試通過選擇較新的人 B 來編輯另一個人的屬性。但是這里更新的是第一個人的屬性(A)。
struct ContentView: View {
@State var selectedItem: Person?
var body: some View {
HStack {
List(selection: $selectedItem) {
ForEach(modelData, id: \.self) { person in
Text(person.firstName)
}
}
.border(.separator, width: 1)
.listStyle(.plain)
.padding()
.frame(width: 200)
VStack {
if let selectedItem = selectedItem {
InformationView(person: PersonModel(person: selectedItem))
} else {
Text("No Item Selected").foregroundColor(Color(NSColor.tertiaryLabelColor))
}
}
.frame(width: 300)
.padding()
}
}
}
信息視圖
struct InformationView: View {
@ObservedObject var person: PersonModel
var body: some View {
Form {
NSTextFieldRepresentable(placeholder: "", text: $person.person.firstName)
NSTextFieldRepresentable(placeholder: "", text: $person.person.secondName)
NSTextFieldRepresentable(placeholder: "", text: $person.person.city)
}
}
}
NSTextField 可表示
struct NSTextFieldRepresentable: NSViewRepresentable {
let placeholder: String
@Binding var text: String
func makeNSView(context: Context) -> NSTextField {
let view = NSTextField()
view.delegate = context.coordinator
return view
}
func updateNSView(_ nsView: NSTextField, context: Context) {
nsView.stringValue = text
nsView.placeholderString = NSLocalizedString(placeholder, comment: "")
}
func makeCoordinator() -> NSTextFieldCoordinator {
NSTextFieldCoordinator(textField: self)
}
class NSTextFieldCoordinator: NSObject, NSTextFieldDelegate {
var textField: NSTextFieldRepresentable
init(textField: NSTextFieldRepresentable) {
self.textField = textField
}
func controlTextDidChange(_ obj: Notification) {
textField.text = (obj.object as? NSTextField)?.stringValue ?? ""
}
}
}
Model class
class Person: NSObject, Identifiable {
var id = UUID()
var firstName: String
var secondName: String
var city: String
init (firstName: String, secondName: String, city: String) {
self.firstName = firstName
self.secondName = secondName
self.city = city
}
}
var modelData: [Person] = [
Person(firstName: "Lionel", secondName: "Messi", city: "Paris"),
Person(firstName: "Cristiano", secondName: "Ronaldo", city: "Manchester"),
Person(firstName: "Sachin", secondName: "Tendulkar", city: "Mumbai"),
Person(firstName: "Virat", secondName: "Kohli", city: "Delhi")
]
class PersonModel: ObservableObject {
@Published var person: Person
init(person: Person) {
self.person = person
}
}
這里
init(textField: NSTextFieldRepresentable) {
self.textField = textField // << copy !!
}
self.textField
是可表示視圖的副本,但在綁定更改時,不會重新創建NSTextFieldRepresentable
- 僅updateNSView
來刷新本機部分,因此協調器在創建時仍然具有復制的值。 這就是問題所在。
此設計中的一個可能修復方法是在綁定更改時更新協調器:
func updateNSView(_ nsView: NSTextField, context: Context) {
nsView.stringValue = text
nsView.placeholderString = NSLocalizedString(placeholder, comment: "")
context.coordinator.textField = self // << here !!
}
使用 Xcode 13.4 / macOS 12.4 測試
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.