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
相关产品推荐
相关产品推荐

