SwiftUI如何实现支持自定义标签高亮的富文本渲染效果
方案1:SwiftUI原生实现(推荐,适配iOS 15及以上)
这个方案不需要引入第三方库,用系统自带的AttributedString就能实现优雅的自定义标签渲染,比逐行拼接Text的方式性能和可维护性都更高。
- 第一步:编写正则匹配自定义标签,提取标签内容和类型,将原始带标签的字符串转换为带样式属性的
AttributedString - 第二步:直接用SwiftUI的
Text组件渲染AttributedString即可
示例代码:
import SwiftUI struct CustomTagText: View { let rawText: String var attributedString: AttributedString { var result = AttributedString() // 正则匹配<f>和<h>标签,可扩展更多自定义标签 let pattern = #"<(f|h)>(.*?)<\/\1>"# let regex = try! NSRegularExpression(pattern: pattern, options: .dotMatchesLineSeparators) let nsRange = NSRange(rawText.startIndex..., in: rawText) var lastEnd = rawText.startIndex for match in regex.matches(in: rawText, options: [], range: nsRange) { // 拼接标签前的普通文本 if let range = Range(match.range(at: 0), in: rawText) { let plainText = String(rawText[lastEnd..<range.lowerBound]) result += AttributedString(plainText) // 处理标签内容 let tagType = rawText[Range(match.range(at: 1), in: rawText)!] let tagContent = String(rawText[Range(match.range(at: 2), in: rawText)!]) var attrContent = AttributedString(tagContent) switch tagType { case "f": // 自定义<f>标签样式,示例为加粗 attrContent.font = .system(size: 16, weight: .bold) case "h": // 自定义<h>标签样式,示例为黄色背景高亮 attrContent.backgroundColor = .yellow default: break } result += attrContent lastEnd = range.upperBound } } // 拼接最后一段普通文本 result += AttributedString(String(rawText[lastEnd...])) return result } var body: some View { Text(attributedString) .font(.system(size: 16)) .lineSpacing(4) } } // 使用示例 // CustomTagText(rawText: DB.getText())
方案2:YYText集成方案(适配低iOS版本/复杂排版需求)
如果需要支持iOS 15以下版本,或者需要更复杂的富文本交互,可以按照以下步骤集成YYText到SwiftUI项目:
- 第一步:通过CocoaPods引入YYText,在Podfile中添加
pod 'YYText'后执行pod install - 第二步:创建OC与Swift的桥接文件,在桥接文件中添加代码
#import <YYText/YYText.h> - 第三步:将YYText的
YYLabel通过UIViewRepresentable封装为SwiftUI可用组件,示例代码如下:
import SwiftUI import UIKit struct YYTextWrapper: UIViewRepresentable { let attributedText: NSAttributedString func makeUIView(context: Context) -> YYLabel { let label = YYLabel() label.numberOfLines = 0 label.preferredMaxLayoutWidth = UIScreen.main.bounds.width - 32 return label } func updateUIView(_ uiView: YYLabel, context: Context) { uiView.attributedText = attributedText } }
- 第四步:参考方案1的解析逻辑,将自定义标签转换为
NSAttributedString,赋值给YYTextWrapper即可使用。
内容的提问来源于stack exchange,提问作者Big_Chair
相关产品推荐
相关产品推荐

