【发布时间】:2021-12-19 11:44:55
【问题描述】:
我首先要解析一个大文本文件并收集所有必要的视图,然后才能最终显示它们。我让它与AnyView 的数组一起工作,但它真的不好,因为它会擦除所有类型。
基本上,我只是想要一个容器来收集里面的视图,直到我最终显示它们。
所以我想知道我是否可以这样做:
class Demo {
var content = VStack()
private func mapInput() {
// ...
}
private func parse() {
for word in mappedInput { // mappedInput is the collection of tags & words that is done before
switch previous {
case "i":
content.add(Text(word).italic())
case "h":
content.add(Text(word).foregroundColor(.green))
case "img":
content.add(Image(word))
}
}
}
}
然后稍后对VStack 做一些事情。但我收到以下错误:
错误:无法推断通用参数“内容”
显式指定通用参数以解决此问题
错误:调用中的参数“内容”缺少参数
插入',内容: _#>'
编辑:
我尝试使用普通的ViewBuilder 来代替。这里的问题是它现在都是独立的Texts,看起来不像一个文本。
struct ViewBuilderDemo: View {
private let exampleInputString =
"""
<i>Welcome.</i><h>Resistance deepens the negative thoughts, acceptance</h><f>This will be bold</f><h>higlight reel</h><f>myappisgood</f>lets go my friend tag parsin in SwiftUI xcode 13 on Mac<img>xcode</img>Mini<f>2020</f><eh>One is beating oneself up, <img>picture</img>the other for looking opportunities. <h>One is a disempowering question, while the other empowers you.</h> Unfortunately, what often comes with the first type of questions is a defensive mindset. You start thinking of others as rivals; you have to ‘fight’ for something so they can't have it, because if one of them gets it then you automatically lose it.
"""
private var mappedInput: [String]
var body: some View {
ScrollView {
VStack(alignment: .leading) {
ForEach(Array(zip(mappedInput.indices, mappedInput)), id: \.0) { index, word in
if index > 0 {
if !isTag(tag: word) {
let previous = mappedInput[index - 1]
switch previous {
case "i":
Text("\(word) ")
.italic()
.foregroundColor(.gray)
case "h":
Text("\(word) ")
.foregroundColor(.green)
.bold()
case "f":
Text("\(word) ")
.bold()
case "eh":
Divider()
.frame(maxWidth: 200)
.padding(.top, 24)
.padding(.bottom, 24)
case "img":
Image(word)
.resizable()
.scaledToFit()
.frame(width: UIScreen.main.bounds.width * 0.7, height: 150)
default:
Text("\(word) ")
}
}
}
}
}
.padding()
}
}
init() {
let separators = CharacterSet(charactersIn: "<>")
mappedInput = exampleInputString.components(separatedBy: separators).filter{$0 != ""}
}
private func isTag(tag currentTag: String) -> Bool {
for tag in Tags.allCases {
if tag.rawValue == currentTag {
return true
}
}
return false
}
enum Tags: String, CaseIterable {
case h = "h"
case hEnd = "/h"
case b = "f"
case bEnd = "/f"
case i = "i"
case iEnd = "/i"
case eh = "eh"
case img = "img"
case imgEnd = "/img"
}
}
【问题讨论】:
-
那样不行,解析和准备模型,然后根据模型的种类有条件地在
body中构造视图。 -
而且,从你放在那里的内容来看,你会想在你的模型中使用“AttributedString”,你可以在以后使用它时控制字符串的外观,至少对于你的文本部分正在显示。见AttributedString documentation。
-
@Yrb 是的,问题是文本之间可以是分隔符和图像,所以我有时必须将文本分成几部分,这使得
ViewBuilder几乎不可能。所以我一直在使用AnyView类型的数组以必要的顺序收集所有的东西,然后显示它。我真的不知道如何做得更好。 -
如果您展示了您想要展示的模型部分,将会有所帮助。你真的没有问你想回答的问题。我会尽可能以Minimal, Reproducible Example 开头一个新问题。
-
@Yrb 我实际上在这里问过这个问题:stackoverflow.com/questions/69800340。所以这里的这个问题就像是在尝试了多种不同的事情之后的后续。
标签: swiftui properties vstack