SwiftUI中如何修改NSTextView的文本选中高亮颜色?
解决SwiftUI中自定义可选文本组件的选中颜色问题
首先要明确:你当前代码里使用的是NSTextField而非NSTextView,这是你设置selectedTextAttributes未生效的核心原因之一。下面提供两种解决方案,对应你使用不同组件的需求:
方案一:修改现有NSTextField的选中高亮颜色
NSTextField的文本选中样式需要通过自定义其字段编辑器来生效,你可以子类化NSTextField,重写获取字段编辑器的方法来注入选中属性:
class CustomSelectableTextField: NSTextField { override func fieldEditor(for controlView: NSView?) -> NSTextView? { let editor = super.fieldEditor(for: controlView) // 设置选中高亮背景色和文本颜色 editor?.selectedTextAttributes = [ NSAttributedString.Key.backgroundColor: NSColor.systemTeal.withAlphaComponent(0.3), NSAttributedString.Key.foregroundColor: NSColor.white ] return editor } }
然后在你的NSViewRepresentable中替换使用这个自定义文本框:
struct SelectableText: NSViewRepresentable { let text: String let font: NSFont? init(text: String, font: NSFont? = nil) { self.text = text self.font = font } func makeNSView(context: Context) -> CustomSelectableTextField { let textField = CustomSelectableTextField(wrappingLabelWithString: text) textField.isBezeled = false textField.isEditable = false textField.isSelectable = true textField.backgroundColor = .clear textField.font = font ?? NSFont.systemFont(ofSize: NSFont.systemFontSize) return textField } func updateNSView(_ nsView: CustomSelectableTextField, context: Context) { nsView.stringValue = text nsView.font = font ?? NSFont.systemFont(ofSize: NSFont.systemFontSize) } }
方案二:改用NSTextView实现可选文本并设置选中颜色
如果你确实需要使用NSTextView(而非NSTextField),可以直接在NSViewRepresentable中配置NSTextView的selectedTextAttributes,同时确保视图的交互设置正确:
struct SelectableTextView: NSViewRepresentable { let text: String let font: NSFont? init(text: String, font: NSFont? = nil) { self.text = text self.font = font } func makeNSView(context: Context) -> NSTextView { let textView = NSTextView() // 配置基础属性 textView.string = text textView.isEditable = false textView.isSelectable = true textView.backgroundColor = .clear textView.font = font ?? NSFont.systemFont(ofSize: NSFont.systemFontSize) // 设置选中文本的样式 textView.selectedTextAttributes = [ NSAttributedString.Key.backgroundColor: NSColor.systemOrange.withAlphaComponent(0.4), NSAttributedString.Key.foregroundColor: NSColor.black ] // 禁用滚动,作为静态文本显示 textView.enclosingScrollView?.hasVerticalScroller = false textView.enclosingScrollView?.hasHorizontalScroller = false textView.enclosingScrollView?.borderType = .noBorder return textView } func updateNSView(_ nsView: NSTextView, context: Context) { nsView.string = text nsView.font = font ?? NSFont.systemFont(ofSize: NSFont.systemFontSize) // 更新时也要确保选中属性保持 nsView.selectedTextAttributes = [ NSAttributedString.Key.backgroundColor: NSColor.systemOrange.withAlphaComponent(0.4), NSAttributedString.Key.foregroundColor: NSColor.black ] } }
关键注意点
- 对于NSTextField:必须通过字段编辑器来设置选中样式,直接设置NSTextField的
selectedTextAttributes不会生效,因为实际编辑/选中逻辑由其内部的字段编辑器处理。 - 对于NSTextView:直接设置
selectedTextAttributes即可生效,但要确保isSelectable设为true,isEditable设为false,同时处理好滚动视图的样式,避免出现不必要的滚动条。
内容的提问来源于stack exchange,提问作者Perch Hakobyan
相关产品推荐
相关产品推荐

