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

SwiftUI View中如何将接口返回内容的标记数字转为彩色上标

实现方案

方案1:iOS 15+ 原生SwiftUI实现(无需借助UIKit)

直接使用SwiftUI原生支持的AttributedString处理样式,无需桥接UIKit,首先修正正则匹配规则,仅匹配*包裹的数字内容:

import SwiftUI

extension String {
    func formattedBibleContent() -> AttributedString {
        var attributedString = AttributedString(self)
        // 修正正则,仅匹配*包裹的数字节号
        guard let regex = try? NSRegularExpression(pattern: "\\*(\\d+)\\*", options: []) else {
            return attributedString
        }
        let nsString = self as NSString
        let matches = regex.matches(in: self, range: NSRange(location: 0, length: nsString.length))
        
        // 倒序遍历匹配项,避免替换后范围偏移问题
        for match in matches.reversed() {
            let fullRange = match.range
            let numberRange = match.range(at: 1)
            let number = nsString.substring(with: numberRange)
            
            if let attributedFullRange = Range(fullRange, in: attributedString) {
                var numberAttr = AttributedString(number)
                // 设置节号样式:橙色、小字号、上标偏移
                numberAttr.foregroundColor = .orange
                numberAttr.font = .system(size: UIFont.systemFontSize - 2)
                numberAttr.baselineOffset = 4
                attributedString.replaceSubrange(attributedFullRange, with: numberAttr)
            }
        }
        return attributedString
    }
}

调用方式直接替换原有Text的内容即可:

List {
  ForEach(self.viewModel.chapters) { chapter in
    Text(chapter.chapter_content_combined.formattedBibleContent())
  }
}

方案2:兼容iOS 15以下版本(借助UIKit实现)

如果需要适配更低系统版本,可以用UIViewRepresentable包装UILabel来渲染富文本:
首先定义富文本渲染组件:

struct AttributedText: UIViewRepresentable {
    let attributedString: NSAttributedString
    
    func makeUIView(context: Context) -> UILabel {
        let label = UILabel()
        label.numberOfLines = 0
        label.lineBreakMode = .byWordWrapping
        return label
    }
    
    func updateUIView(_ uiView: UILabel, context: Context) {
        uiView.attributedText = attributedString
    }
}

编写对应的字符串处理扩展:

extension String {
    func formattedBibleContent() -> NSAttributedString {
        let attributedString = NSMutableAttributedString(string: self, attributes: [
            .font: UIFont.systemFont(ofSize: UIFont.systemFontSize),
            .foregroundColor: UIColor.label
        ])
        guard let regex = try? NSRegularExpression(pattern: "\\*(\\d+)\\*", options: []) else {
            return attributedString
        }
        let matches = regex.matches(in: self, range: NSRange(location: 0, length: self.count))
        
        for match in matches.reversed() {
            let fullRange = match.range
            let numberRange = match.range(at: 1)
            let number = (self as NSString).substring(with: numberRange)
            
            let numberAttr: [NSAttributedString.Key: Any] = [
                .foregroundColor: UIColor.orange,
                .font: UIFont.systemFont(ofSize: UIFont.systemFontSize - 2),
                .baselineOffset: 4
            ]
            let attributedNumber = NSAttributedString(string: number, attributes: numberAttr)
            attributedString.replaceCharacters(in: fullRange, with: attributedNumber)
        }
        return attributedString
    }
}

调用方式:

List {
  ForEach(self.viewModel.chapters) { chapter in
    AttributedText(attributedString: chapter.chapter_content_combined.formattedBibleContent())
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 04:15:06