Как я могу создать SwiftUI TextView, который будет обновлять привязку при создании нового представления
Я попытался использовать класс Coordinator для создания TextView, но, похоже, он всегда сохраняет привязку к исходному объекту.
Если я использую это в представлении SwiftUI, как это, то если я использую DocView в расположении мастер / подробности и передаю новый объект Doc, тогда TextView всегда будет удерживать привязку к первому документу.
Итак, если есть список документов или элементов, тогда, когда выбран второй или третий документ и для этого документа создается DocView, любые изменения в TextView обновят сведения о первых документах.
Таким образом, похоже, что Координатор или что-то еще сохраняет исходную привязку, а не обновляет, чтобы отразить последний экземпляр переменной doc DocView.
Я неправильно понял, как должен работать Координатор, и если да, то как я могу убедиться, что при создании нового DocView (doc: newdocobject) привязка будет обновлена.
На практике TextView будет отображать детали newdocobject, но каждый раз, когда выполняется какое-либо редактирование, цель все еще остается исходным объектом.
РЕДАКТИРОВАТЬ: образец приложения https://duncangroenewald.com/files/SampleApps/TextView.zip
Лучшая иллюстрация проблемы https://duncangroenewald.com/files/SampleApps/TextView2.zip
struct DocView: View {
@ObservedObject var doc: Doc
var body: some View {
TextView(attributedText: $doc.details)
}
}
class Doc: NSObject, ObservableObject {
var name: String
var details: NSAttributedString
init(name: String) {
self.name = name
self.details = NSAttributedString(string:"New doc details")
}
}
//
// TextView.swift
// DocApp
//
// Created by Duncan Groenewald on 11/12/21.
// Copyright © 2021 Apple. All rights reserved.
//
import Foundation
import SwiftUI
#if !os(macOS)
struct TextView: UIViewRepresentable {
@Binding var attributedText: NSAttributedString
func makeUIView(context: Context) -> OSTextView {
let textView = OSTextView()
textView.delegate = context.coordinator
return textView
}
func updateUIView(_ uiView: OSTextView, context: Context) {
uiView.attributedText = attributedText
}
func makeCoordinator() -> Coordinator {
Coordinator($attributedText)
}
class Coordinator: NSObject, UITextViewDelegate {
var text: Binding<NSAttributedString>
init(_ text: Binding<NSAttributedString>) {
self.text = text
}
func textViewDidChange(_ textView: UITextView) {
self.text.wrappedValue = textView.attributedText
}
}
}
#endif
#if os(macOS)
struct TextView: NSViewRepresentable {
@Binding var attributedText: NSAttributedString
func makeNSView(context: Context) -> OSTextView {
let textView = OSTextView(frame: .zero)
textView.delegate = context.coordinator
return textView
}
func updateNSView(_ nsView: OSTextView, context: Context) {
nsView.textStorage?.setAttributedString(attributedText)
}
func makeCoordinator() -> Coordinator {
return Coordinator($attributedText)
}
class Coordinator: NSObject, NSTextViewDelegate {
var text: Binding<NSAttributedString>
init(_ text: Binding<NSAttributedString>) {
self.text = text
super.init()
}
func textDidChange(_ notification: Notification) {
if let textView = notification.object as? NSTextView {
self.text.wrappedValue = textView.attributedString()
}
}
}
}
#endif