【问题标题】:Handle keyboard inputs in NSTextView embedded via NSViewRepresentable? (SwiftUI/MacOS)处理通过 NSViewRepresentable 嵌入的 NSTextView 中的键盘输入? (SwiftUI/MacOS)
【发布时间】:2020-10-25 03:08:33
【问题描述】:

我是 SwiftUI 的新手,完全糊涂了。我设法将 NSTextView 嵌入到我的 SwiftUI 视图中,并将其文本与以下代码绑定。

我不明白的;有没有办法处理键盘输入到 NSTextView 并相应地更改其文本(例如 CMD + R 将所选文本的文本颜色设置为红色)?有没有办法在 SwiftUI 中与 UI 元素进行交互?

“RichTextField”

struct RichTextField: NSViewRepresentable {
    typealias NSViewType = NSTextView
    
    @Binding var attributedString: NSAttributedString 

    func makeNSView(context: Context) -> NSTextView {...
    // [...]

}

查看

struct EditWindow: View {
      
  @ObservedObject var model: EditEntryViewModel
  @Binding var isPresented: Bool
        
  var body: some View {    
     RichTextField(attributedString: self.$model.answer1, isEditable: true)
      // [...]
    }
}

此外,我已经设法在 AppDelegate 中设置了一个菜单命令,但是我如何使用它来更改任意 View 的 NSTextView 中的文本(在某个位置)?

@IBAction func setTagImportant(_ sender: Any) {
  print("setTagImportant")
}

非常感谢您为我阐明了这一点...

【问题讨论】:

    标签: swift macos swiftui nstextview


    【解决方案1】:

    具有讽刺意味的是,在最后发布这个问题后,我立即找到了解决方案;简单地将 NSTextView 子类化,然后覆盖 keyDown:

    import SwiftUI
    
    class RichTextFieldExtended: NSTextView {
        
        override func keyDown(with event: NSEvent) {
            
            if event.modifierFlags.contains(NSEvent.ModifierFlags.command) {
                
                switch event.keyCode {
                    
                case 18: // 1
                    
                    print("1 PRESSED")                
                    
                default:
                    print("keyCode \(event.keyCode) wasn't handled")
                    super.keyDown(with: event)
                }
                
            } else {
                super.keyDown(with: event)
            }
            
        }
        
    }
    

    然后在NSViewRepresentable中包含子类的NSTextView,如下

    struct RichTextField: NSViewRepresentable {
        typealias NSViewType = RichTextFieldExtended
        
        @Binding var attributedString: NSAttributedString
        var isEditable: Bool
        
        func makeCoordinator() -> Coordinator {
            Coordinator(self)
        }
    
        func makeNSView(context: Context) -> RichTextFieldExtended {
            let textView = RichTextFieldExtended(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: RichTextFieldExtended, 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? RichTextFieldExtended else { return }
                self.parent.attributedString = textView.attributedString()
    
            }
    
        }
        
    }
    

    干杯

    【讨论】:

      猜你喜欢
      • 2010-09-23
      • 2017-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多