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

SwiftUI中NSMutableParagraphStyle段落样式不生效问题及解决

问题描述

我需要给包含阿拉伯语和英语的混合文本添加富文本属性:通过NSMutableAttributedString修改阿拉伯语部分的颜色、字体,同时用NSMutableParagraphStyle设置右对齐、行间距等段落样式。目前阿拉伯语的颜色修改已生效,但段落样式在SwiftUI的Text组件中完全不生效,不过相同的富文本在UIKit的UITextView里能正常显示所有样式。

相关代码如下:

富文本样式处理代码

let arabicChars = try? NSRegularExpression(pattern: "[\\u0600-\\u06FF\\u0750-\\u077F\\u08A0-\\u08FF\\uFB50-\\uFDFF\\uFE70-\\uFEFF\\s]+", options: [])
arabicChars?.enumerateMatches(in: pureText, options: [], range: range) { (result, _, _) in
    if let subStringRange = result?.range(at: 0) {
        stringText.addAttribute(.foregroundColor, value: UIColor(.brown), range: subStringRange)
        
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.alignment = .right
        paragraphStyle.lineSpacing = 1.2
        paragraphStyle.lineHeightMultiple = 1.2
        stringText.addAttribute(.paragraphStyle, value: paragraphStyle, range: subStringRange)
        stringText.addAttribute(.font, value: UIFont(name: "CustomFont", size: 16)!, range: subStringRange)
    }
}

SwiftUI调用代码

var body: some View {
    ScrollView {
        VStack(alignment: .leading, spacing: 15) {
            Text(word.word?.capitalized ?? "")
                .font(.system(size: 32, weight: .bold, design: .serif))
        
            Text(AttributedString(applyAttributedStyle(word.meaning)))
        }
        .frame(maxWidth: .infinity, alignment: .leading)
    }
    .padding(.horizontal)
}
原因分析

SwiftUI的Text组件对AttributedString的段落样式支持存在局限性,尤其是针对局部文本的段落样式设置。它仅能识别字体、颜色这类基础属性,无法像UIKit的UITextView那样完整解析并应用NSMutableParagraphStyle中的对齐、行间距等高级段落属性。

解决方案

通过UIViewRepresentable封装UIKit的UITextView,利用UIKit对富文本的完整支持来显示带段落样式的混合文本。

封装UITextView组件

struct AttributedTextView: UIViewRepresentable {
    var attributedString: NSAttributedString
    
    func makeUIView(context: Context) -> UITextView {
        let textView = UITextView()
        textView.isEditable = false
        textView.isScrollEnabled = false
        textView.backgroundColor = .clear
        return textView
    }
    
    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.attributedText = attributedString
    }
}

替换SwiftUI中的Text组件

把原代码里的Text(AttributedString(...))替换为封装好的组件:

var body: some View {
    ScrollView {
        VStack(alignment: .leading, spacing: 15) {
            Text(word.word?.capitalized ?? "")
                .font(.system(size: 32, weight: .bold, design: .serif))
        
            AttributedTextView(attributedString: applyAttributedStyle(word.meaning))
        }
        .frame(maxWidth: .infinity, alignment: .leading)
    }
    .padding(.horizontal)
}

这样就能完整显示包含段落样式的阿拉伯语和英语混合文本了。

内容的提问来源于stack exchange,提问作者Mc.Lover

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 10:17:33