我正在编写的 SwiftUI 应用程序有大块文本,因此我尝试创建一种“标记语言”,可以在保存文本的 JSON 文件中使用,以定义何时应将单词加粗。问题是,我似乎无法阻止新的文本 block 进入不同的行。
这是我目前拥有的相关代码。
struct formattedText: View {
var text: String
var body: some View {
let split = text.components(separatedBy: "**")
Group {
ForEach(split, id: \.self) { line in
if line.hasPrefix("$$") {
Text(line.trimmingCharacters(in: CharacterSet(charactersIn: "$")))
.bold()
} else {
Text(line)
}
}
}
.lineLimit(nil)
.multilineTextAlignment(.leading)
}
使用此代码,我可以在单词之前放置 **$$
,在单词之后放置 **
,将其定义为粗体。
唯一的问题是每次我加粗一个单词时它都会换行。我知道解决这个问题的传统方法是:
Text("Simple ") + Text("Swift ") + Text("Guide")
但这不适用于我的 ForEach 循环。有什么建议吗?
最佳答案
ForEach
创建单独的 View 。你真的只想要一个文本,所以你的意思是一个 for...in
循环:
var body: some View {
let split = text.components(separatedBy: "**")
var result = Text("")
for line in split {
if line.hasPrefix("$$") {
result = result + Text(line.trimmingCharacters(in: CharacterSet(charactersIn: "$")))
.bold()
} else {
result = result + Text(line)
}
}
return result
.lineLimit(nil)
.multilineTextAlignment(.leading)
}
由于您可能想要的不仅仅是粗体,因此您可能会发现将该部分提取到其自己的函数或函数集合中很有用:
private func applyAttributes(line: String) -> Text {
if line.hasPrefix("$$") {
return Text(line.trimmingCharacters(in: CharacterSet(charactersIn: "$")))
.bold()
} else {
return Text(line)
}
}
有了这个,构建就更简单了:
var body: some View {
text.components(separatedBy: "**")
.map(applyAttributes)
.reduce(Text(""), +)
.lineLimit(nil)
.multilineTextAlignment(.leading)
}
关于ios - SwiftUI:在同一行组合文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66878953/