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

如何在SwiftUI的TextEditor中使用AttributedString?

在SwiftUI的TextEditor中使用AttributedString实现#开头文本着色

问题背景

我目前在SwiftUI中使用基于String类型的TextEditor,想要改用AttributedString,实现将所有以#开头的文本段标记为不同颜色。但编写如下代码后出现错误:

struct PlaygroundView: View {
    @State private var text = AttributedString("")
    var body: some View {
        TextEditor(text: text)
    }
}

错误提示:

Cannot convert value of type 'AttributedString' to expected argument type 'Binding'

问题原因

SwiftUI原生的TextEditor仅支持绑定String类型,不直接兼容AttributedString,因此直接传入会触发类型不匹配的报错。

解决方案

要实现富文本编辑并给#开头文本着色,推荐使用UIKit的UITextView包装成SwiftUI组件的方案,以下是具体实现:

步骤1:封装支持NSAttributedString的TextEditor

创建UIViewRepresentable结构体,将UITextView包装为SwiftUI可用的组件,同时处理文本变化时的着色逻辑:

import SwiftUI
import UIKit

struct AttributedTextEditor: UIViewRepresentable {
    @Binding var attributedText: NSAttributedString
    // 可自定义默认文本颜色和标签颜色
    var defaultTextColor: UIColor = .label
    var hashtagColor: UIColor = .systemBlue
    
    func makeUIView(context: Context) -> UITextView {
        let textView = UITextView()
        textView.delegate = context.coordinator
        textView.font = UIFont.preferredFont(forTextStyle: .body)
        textView.backgroundColor = .clear // 适配SwiftUI背景
        return textView
    }
    
    func updateUIView(_ uiView: UITextView, context: Context) {
        // 避免循环更新,仅当外部文本变化时同步
        if uiView.attributedText != attributedText {
            uiView.attributedText = attributedText
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, UITextViewDelegate {
        let parent: AttributedTextEditor
        
        init(_ parent: AttributedTextEditor) {
            self.parent = parent
        }
        
        func textViewDidChange(_ textView: UITextView) {
            let mutableText = NSMutableAttributedString(attributedString: textView.attributedText)
            
            // 重置所有文本为默认颜色
            mutableText.addAttribute(
                .foregroundColor,
                value: parent.defaultTextColor,
                range: NSRange(location: 0, length: mutableText.length)
            )
            
            // 正则匹配所有#开头的单词(支持中英文)
            let hashtagPattern = "#\\w+"
            let regex = try! NSRegularExpression(pattern: hashtagPattern, options: [])
            let matches = regex.matches(
                in: mutableText.string,
                range: NSRange(location: 0, length: mutableText.length)
            )
            
            // 给匹配到的#标签设置颜色
            for match in matches {
                mutableText.addAttribute(
                    .foregroundColor,
                    value: parent.hashtagColor,
                    range: match.range
                )
            }
            
            parent.attributedText = mutableText
        }
    }
}

步骤2:在SwiftUI视图中使用封装好的组件

struct PlaygroundView: View {
    @State private var attributedText = NSAttributedString(string: "")
    
    var body: some View {
        AttributedTextEditor(attributedText: $attributedText)
            .padding()
            .frame(minHeight: 200)
            .border(Color.gray.opacity(0.3))
    }
}

关键说明

  • 利用UITextView原生支持NSAttributedString的特性,通过UIViewRepresentable桥接到SwiftUI
  • Coordinator作为UITextView的代理,监听文本变化并实时处理#标签的着色逻辑
  • 可通过修改defaultTextColor和hashtagColor参数自定义颜色样式

内容的提问来源于stack exchange,提问作者Paul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:25:27