gpt4 book ai didi

swift - 如何让 Swift Coordinator 反射(reflect) parent 的绑定(bind)变化?

转载 作者:行者123 更新时间:2023-12-04 15:26:39 25 4
gpt4 key购买 nike

假设我有:

  • 结构Document , 表示文本文档。
  • EditorViewNSTextView , 用 Combine 包装,绑定(bind)到 Document.content<String> .

Document是复杂 store:ObservableObject 的一部分, 所以它可以被限制为 EditorView实例。

当我第一次创建绑定(bind)时,它按预期工作——编辑 NSTextView 更改 Document.content 中的值.

let document1 = Document(...)
let document2 = Document(...)
var editor = EditorView(doc: document1)

但是如果改变绑定(bind)到另一个文档...

editor.doc = document2

...然后updateNSView可以看到新document2 .但是在 Coordiantor 的 textDidChange 里面仍然引用 document1 .

func textDidChange(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else {
return
}

self.parent.doc.content = textView.string
self.selectedRanges = textView.selectedRanges
}

所以,最初,当我设置新的 bindint 时,NSTextView 将其内容更改为 document2 , 但在我键入时,协调器将更改发送到 document1 .

是真的吗,Coordiantor 保留了它自己的 parent 副本,即使父级更改(@Binding doc 已更新),它仍然引用旧的吗?

如何让 Coordinator 反射(reflect)父绑定(bind)的变化?

谢谢!

struct Document: Identifiable, Equatable {
let id: UUID = UUID()
var name: String
var content: String
}

struct EditorView: NSViewRepresentable {
@Binding var doc: Document

func makeCoordinator() -> Coordinator {
Coordinator(self)
}

func makeNSView(context: Context) -> CustomTextView {
let textView = CustomTextView(
text: doc.content,
isEditable: isEditable,
font: font
)
textView.delegate = context.coordinator

return textView
}

func updateNSView(_ view: CustomTextView, context: Context) {
view.text = doc.content
view.selectedRanges = context.coordinator.selectedRanges

}
}


// MARK: - Coordinator

extension EditorView {

class Coordinator: NSObject, NSTextViewDelegate {
var parent: EditorView
var selectedRanges: [NSValue] = []

init(_ parent: EditorView) {
self.parent = parent
}

func textDidBeginEditing(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else {
return
}

self.parent.doc.content = textView.string
self.parent.onEditingChanged()
}

func textDidChange(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else {
return
}

self.parent.doc.content = textView.string
self.selectedRanges = textView.selectedRanges
}

func textDidEndEditing(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else {
return
}

self.parent.doc.content = textView.string
self.parent.onCommit()
}
}
}

// MARK: - CustomTextView

final class CustomTextView: NSView {
private var isEditable: Bool
private var font: NSFont?

weak var delegate: NSTextViewDelegate?

var text: String {
didSet {
textView.string = text
}
}
// ...

最佳答案

Is it true, that Coordiantor keeps it's own copy of parent, and even if parent changes (@Binding doc is updated), it still references to old one?

一个parent,即这里的EditorView,是struct,所以答案是肯定的,一般是可以复制的。

How to make Coordinator reflect parent's bindings changes?

代替(或附加于)父级,将绑定(bind)显式注入(inject) Coordinator(通过构造函数)并直接使用它。

关于swift - 如何让 Swift Coordinator 反射(reflect) parent 的绑定(bind)变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62116329/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com