我尝试将查找栏添加到 SwiftUI 视图中的 NSTextView,但尽管设置了必要的属性(usesFindBar、usesFindPanel、isIncrementalSearchingEnabled),但查找栏并未出现。这是我正在使用的代码:
import AppKit
struct TextView: NSViewRepresentable {
@Binding var selectedRange: NSRange?
@Binding var text: String
var onAddingNewLine: (() -> Void)?
@Binding var textToReplace: (text: String, range: NSRange)?
@Binding var shouldInsertText: Bool?
func makeNSView(context: Context) -> NSScrollView {
let scrollView = NSTextView.scrollableTextView()
guard let textView = scrollView.documentView as? NSTextView else {
return scrollView
}
textView.allowsUndo = true
textView.usesFindBar = true
textView.usesFindPanel = false
textView.isIncrementalSearchingEnabled = true
textView.window?.makeFirstResponder(textView)
textView.isContinuousSpellCheckingEnabled = true
textView.font = NSFont.monospacedSystemFont(ofSize: 15, weight: .regular)
textView.textColor = NSColor(Color.onSurface)
DispatchQueue.main.async {
textView.string = text
textView.delegate = context.coordinator
}
return scrollView
}
func updateNSView(_ scrollView: NSScrollView, context: Context) {
guard let textView = scrollView.documentView as? NSTextView else {
return
}
if let textToReplace {
DispatchQueue.main.async {
let textToInsert = textToReplace
self.textToReplace = nil
if shouldInsertText ?? false {
textView.insertText(textToInsert.text, replacementRange: textToInsert.range)
}
shouldInsertText = false
}
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, NSTextViewDelegate {
var parent: TextView
init(_ parent: TextView) {
self.parent = parent
}
func textDidEndEditing(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else { return }
parent.text = textView.string
textView.undoManager?.removeAllActions()
}
func textDidChange(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else { return }
let string = textView.string
let length = string.count
let insertionPoint = textView.selectedRange.location
let low = max(0, insertionPoint - 1)
if let range = Range(NSRange(location: low, length: 1), in: string) {
let newChar = string[range]
if length > 0 && length > parent.text.count, newChar == "\n" {
parent.text = textView.string
parent.onAddingNewLine?()
} else {
parent.text = textView.string
}
} else {
parent.text = textView.string
}
}
func textViewDidChangeSelection(_ notification: Notification) {
guard let textView = notification.object as? NSTextView else { return }
parent.selectedRange = textView.selectedRange
}
}
}
此属性(usesFindBar、usesFindPanel、isIncrementalSearchingEnabled)在使用通过 Storyboard 创建的 NSTextView 时有效,但在 SwiftUI 中使用时无效。
还使用此 MacEditorTextView
尝试了 Findbar任何有关查找栏未显示原因的见解将不胜感激!
我能够通过创建此扩展来实现此功能
extension NSTextView {
func showFindBar() {
let menuItem = NSMenuItem(title: "", action: nil, keyEquivalent: "")
menuItem.tag = NSTextFinder.Action.showFindInterface.rawValue
self.performTextFinderAction(menuItem)
}
}
我也搬到了
textView.window?.makeFirstResponder(textView)
到DispatchQueue.main.async
然后我只需通过
.commands { CommandGroup(after: .undoRedo) }
从绑定到键盘快捷键 F 的自定义菜单栏项调用 showFindBar 函数