You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 05:35:30