【问题标题】:Binding with "RichTextField" (i.e. NSTextView in NSViewRepresentable) - Value resets after redraw, LostFocus, etc与“RichTextField”绑定(即 NSViewRepresentable 中的 NSTextView) - 重绘、LostFocus 等后重置值
【发布时间】:2020-06-28 21:23:03
【问题描述】:

我正在努力使用定制的 RichTextField,即 NSViewRepresentable 中的 NSTextView,它具有以下代码(在 How to use an NSAttributedString with a ScrollView in SwiftUI? 的帮助下编程):

在代码中设置属性字符串有效,我可以更改格式,但一旦应用程序失去焦点,RichTextField 就会重置为以编程方式设置的最后一个值

此外,当在 List 中使用 RichTextField 时,应用程序会进入循环。

RichTextField

import Foundation
import SwiftUI

struct RichTextField: NSViewRepresentable {
    typealias NSViewType = NSTextView
    
    @Binding var attributedString: NSMutableAttributedString 
    var isEditable: Bool
    
    func makeNSView(context: Context) -> NSTextView {
        let textView = NSTextView(frame: .zero)

        textView.textStorage?.setAttributedString(self.attributedString)
        textView.isEditable = isEditable

        textView.translatesAutoresizingMaskIntoConstraints = false 
        textView.autoresizingMask = [.width, .height] 

        return textView
    }

    func updateNSView(_ nsView: NSTextView, context: Context) {
        nsView.textStorage?.setAttributedString(self.attributedString)
    }

}

查看

import SwiftUI

struct EditWindow: View {
    
    @ObservedObject var model: EditEntryViewModel
    
 var body: some View {

        VStack (alignment: .leading, spacing: 20) {
            
            RichTextField(attributedString: self.$model.answer1, isEditable: true)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
            Spacer()
            
        }.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
        
    }
    
}

视图模型

import Foundation
import SwiftUI

class EditEntryViewModel: ObservableObject {
    
    init(entryID: Int32) {
        
        let entryToUse = db.getEntry(id: entryID)
        
        id = entryToUse!.id
        answer1 = entryToUse!.answer1.getNSMutableAttributedStringFromHTML() // Converts HTML from the DB to a NSMutableAttributedString
        
    }
    
    @Published var id: Int32
    @Published var answer1: NSMutableAttributedString = NSMutableAttributedString() {
        didSet {
            print("NEW answer1: " + answer1.string)
        }
    }
    
}

不知道有没有办法将attributeString绑定到ViewModel?

非常感谢您的帮助。

【问题讨论】:

    标签: macos swiftui nstextview


    【解决方案1】:

    不确定这是否是正确的方法,但我得到了绑定以使用以下代码:

    import Foundation
    import SwiftUI
    
    
    struct RichTextField: NSViewRepresentable {
        typealias NSViewType = NSTextView
        
        @Binding var attributedString: NSAttributedString  
        var isEditable: Bool
        
        func makeCoordinator() -> Coordinator {
            Coordinator(self)
        }
    
        func makeNSView(context: Context) -> NSTextView {
            let textView = NSTextView(frame: .zero)
            
            textView.textStorage?.setAttributedString(self.attributedString)
            textView.isEditable = isEditable
            textView.delegate = context.coordinator
            
            textView.translatesAutoresizingMaskIntoConstraints = false 
            textView.autoresizingMask = [.width, .height] 
    
            return textView
        }
    
        func updateNSView(_ nsView: NSTextView, context: Context) {
            nsView.textStorage!.setAttributedString(self.attributedString)
        }
    
        // Source: https://medium.com/fantageek/use-xib-de9d8a295757
        class Coordinator: NSObject, NSTextViewDelegate {
            let parent: RichTextField
            
            init(_ RichTextField: RichTextField) {
                self.parent = RichTextField
            }
    
            func textDidChange(_ notification: Notification) {
    
                guard let textView = notification.object as? NSTextView else { return }
                self.parent.attributedString = textView.attributedString()
    
            }
    
        }
        
    }
    

    (尽管在列表(不可编辑)中使用 RichTextField 时,我仍然收到“检测到循环”错误..)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 2015-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多