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

SwiftUI:同一Text视图内实现不同文本颜色

解决SwiftUI中替换文本部分样式的问题

你现在的问题核心是:直接用replacingOccurrences会把整个文本变成统一样式的Text视图,没法单独给用户答案设置不同颜色。这里有两种适合SwiftUI新手的实现方法,逻辑清晰好上手:

方法1:拼接多个Text视图(最直观)

这种方法就像拼积木,把原文本拆成「替换标记前的内容」「用户答案」「替换标记后的内容」三部分,分别创建Text并设置样式,最后用+拼接起来:

let questionText = question.text
let placeholder = "_____"

// 先检查原文本里有没有替换标记,避免崩溃
guard let placeholderRange = questionText.range(of: placeholder) else {
    // 如果没找到标记,直接显示原文本
    return Text(questionText)
        .font(Font.custom("ClearSans-Bold", size: 18))
        .foregroundColor(.black)
        .multilineTextAlignment(.center)
        .padding(.bottom, 20)
}

// 拆分文本为前缀、后缀
let prefixText = String(questionText[..<placeholderRange.lowerBound])
let suffixText = String(questionText[placeholderRange.upperBound...])
let userAnswerText = question.answers[question.userAnswer]

// 拼接不同样式的Text
Text(prefixText)
    .font(Font.custom("ClearSans-Bold", size: 18))
    .foregroundColor(.black)
+ Text(userAnswerText)
    .font(Font.custom("ClearSans-Bold", size: 18))
    .foregroundColor(.red) // 可以根据答案对错切换颜色:比如 question.isAnswerCorrect ? .green : .red
+ Text(suffixText)
    .font(Font.custom("ClearSans-Bold", size: 18))
    .foregroundColor(.black)
    .multilineTextAlignment(.center)
    .padding(.bottom, 20)

这种方法逻辑简单,你能清晰看到每一部分的样式设置,完全不需要处理复杂的字符串范围,新手友好度拉满。

方法2:使用AttributedString(适合复杂样式扩展)

如果以后需要更复杂的文本样式(比如不同字体、下划线、字间距等),可以用AttributedString统一管理样式:

let questionText = question.text
let placeholder = "_____"
guard let placeholderRange = questionText.range(of: placeholder) else {
    return Text(questionText)
        .font(Font.custom("ClearSans-Bold", size: 18))
        .foregroundColor(.black)
        .multilineTextAlignment(.center)
        .padding(.bottom, 20)
}

let userAnswerText = question.answers[question.userAnswer]
// 生成替换标记后的完整文本
let fullText = questionText.replacingOccurrences(of: placeholder, with: userAnswerText)

// 创建AttributedString并设置基础样式
var attributedString = AttributedString(fullText)
attributedString.font = Font.custom("ClearSans-Bold", size: 18)
attributedString.foregroundColor = .black

// 找到用户答案的范围,单独设置颜色
if let answerRange = attributedString.range(of: userAnswerText) {
    attributedString[answerRange].foregroundColor = .red // 同样支持按对错切换颜色
}

// 显示带样式的文本
Text(attributedString)
    .multilineTextAlignment(.center)
    .padding(.bottom, 20)

两种方法都能实现你要的效果,新手推荐先从第一种拼接Text的方法入手,更容易理解和调试。如果需要根据答案对错切换红绿色,只需要把颜色设置改成条件判断就行——比如假设你的Question模型有个isUserAnswerCorrect属性,就写成.foregroundColor(question.isUserAnswerCorrect ? .green : .red)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 23:52:38