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

SwiftUI实现文本逐行高亮(非整文本框)及背景内边距设置

SwiftUI 实现文本逐行高亮效果

需求说明

需要实现文本逐行单独高亮的效果(而非高亮整个文本框),暂未找到最优方案,曾尝试复用文本变量、添加背景色、缩小字体制造间距并将文本设为透明的思路,当前使用SwiftUI,寻求可行实现方案。

当前用于文本对齐的代码如下:

struct LabelAlignment: UIViewRepresentable {
    var text: String
    var textAlignmentStyle : TextAlignmentStyle
    var width: CGFloat
    var fontName: String
    var fontSize: CGFloat
    var fontColor: UIColor

    func makeUIView(context: Context) -> UILabel {
        let font = UIFont(name: fontName, size: fontSize)
        let label = UILabel()
        label.textAlignment = NSTextAlignment(rawValue: textAlignmentStyle.rawValue)!
        label.numberOfLines = 0
        label.preferredMaxLayoutWidth = width
        label.font = font
        label.setContentHuggingPriority(.required, for: .horizontal)
        label.setContentHuggingPriority(.required, for: .vertical)
        label.textColor = fontColor

        return label
    }

    func updateUIView(_ uiView: UILabel, context: Context) {
        uiView.text = text
    }
}

enum TextAlignmentStyle : Int{
     case left = 0 ,center = 1 , right = 2 ,justified = 3 ,natural = 4
}

预期效果

预期每行文本带有独立背景高亮,效果如下:
预期文本逐行高亮效果

实现方案

基于你现有的UIViewRepresentable封装逻辑,通过NSAttributedString结合文本排版计算,为每行文本添加背景色属性,具体实现如下:

1. 修改LabelAlignment组件,添加逐行高亮逻辑

struct LabelAlignment: UIViewRepresentable {
    var text: String
    var textAlignmentStyle: TextAlignmentStyle
    var width: CGFloat
    var fontName: String
    var fontSize: CGFloat
    var fontColor: UIColor
    var highlightColor: UIColor // 新增高亮色参数

    func makeUIView(context: Context) -> UILabel {
        let font = UIFont(name: fontName, size: fontSize) ?? UIFont.systemFont(ofSize: fontSize)
        let label = UILabel()
        label.textAlignment = NSTextAlignment(rawValue: textAlignmentStyle.rawValue)!
        label.numberOfLines = 0
        label.preferredMaxLayoutWidth = width
        label.font = font
        label.setContentHuggingPriority(.required, for: .horizontal)
        label.setContentHuggingPriority(.required, for: .vertical)
        label.textColor = fontColor

        return label
    }

    func updateUIView(_ uiView: UILabel, context: Context) {
        let attributedText = NSMutableAttributedString(string: text)
        let font = uiView.font ?? UIFont.systemFont(ofSize: fontSize)
        
        // 设置基础文本属性
        attributedText.addAttribute(.font, value: font, range: NSRange(location: 0, length: attributedText.length))
        attributedText.addAttribute(.foregroundColor, value: fontColor, range: NSRange(location: 0, length: attributedText.length))
        
        // 计算每行文本范围
        let layoutManager = NSLayoutManager()
        let textContainer = NSTextContainer(size: CGSize(width: width, height: .greatestFiniteMagnitude))
        let textStorage = NSTextStorage(attributedString: attributedText)
        
        layoutManager.addTextContainer(textContainer)
        textStorage.addLayoutManager(layoutManager)
        textContainer.lineFragmentPadding = 0
        textContainer.maximumNumberOfLines = 0
        textContainer.lineBreakMode = uiView.lineBreakMode
        
        var lineRange = NSRange()
        var index = 0
        while index < textStorage.length {
            // 获取当前行范围
            layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
            // 为当前行添加高亮背景色
            attributedText.addAttribute(.backgroundColor, value: highlightColor, range: lineRange)
            index = NSMaxRange(lineRange)
        }
        
        uiView.attributedText = attributedText
    }
}

enum TextAlignmentStyle: Int {
    case left = 0, center = 1, right = 2, justified = 3, natural = 4
}

2. SwiftUI视图中调用示例

struct ContentView: View {
    var body: some View {
        LabelAlignment(
            text: "这是一段测试文本,用于展示逐行高亮的效果。当文本内容超过一行时,每一行都会带有独立的背景高亮,而不是整个文本框统一高亮。",
            textAlignmentStyle: .left,
            width: 300,
            fontName: "PingFangSC-Regular",
            fontSize: 16,
            fontColor: .black,
            highlightColor: UIColor.yellow.withAlphaComponent(0.3)
        )
        .padding()
    }
}

方案优势

  • 基于现有封装逻辑扩展,无需重构原有代码
  • 通过NSLayoutManager精准计算每行范围,高亮效果准确
  • 支持自定义高亮颜色、透明度,适配所有文本对齐方式

内容的提问来源于stack exchange,提问作者za.ch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 01:10:22