I have a Text() view inside a HStack inside of a ForEach inside of a VStack. The text can be a string of any length, and I have no control of that is put inside of it. The problem is that when you run the program, the views in the VStack overlap resulting in this jumbled mess
What I want to do is have a view that resizes its height based on the height of the multi line text view, so that the views never overlap, and always displays the entirety of the string.
Here is some code that generates the view in question:
struct ScrollingChatView: View {
@State var model: WatchModel
@State var messages: [DisplayableMessage] = []
var body: some View {
ScrollView {
if (!messages.isEmpty) {
LazyVStack {
ForEach(messages, id: \.sortTimestamp) { message in
CompactChatView(message: message)
}
}.padding()
} else {
Text("Getting Chat...").padding()
}
}.onReceive(model.chatDriver.publisher) { m in
self.messages = m
}
}
}
struct CompactChatView: View {
@State var message: DisplayableMessage
@State var stringMessage: String? = nil
var body: some View {
VStack(alignment: .leading) {
HStack(alignment: .top) {
Text(message.displayAuthor)
.lineLimit(1)
.layoutPriority(1)
Group {
Text(getEmojiText(message))
.font(.headline)
.fixedSize(horizontal: false, vertical: true)
}
Spacer()
Text(message.displayTimestamp)
.font(.subheadline)
.foregroundColor(Color.gray)
.layoutPriority(1)
}.padding(.all, 6.0)
}
}
func getEmojiText(_ item: DisplayableMessage) -> String {
var fullMessage: String = ""
for m in item.displayMessage {
switch m {
case .text(let s):
fullMessage += s
case .emote(_):
print()
}
}
return fullMessage
}
}
I've tried removing .fixedSize(horizontal: false, vertical: true) from the text view, but it only makes the text cut off after one line, which is not what I want.
If you need more context, the entire project in located at: https://github.com/LiveTL/apple. We're looking at code in the macOS folder.