SwiftUI:VStack 中 ForEach 中的 HStack 使多行文本重叠

Posted

技术标签:

【中文标题】SwiftUI:VStack 中 ForEach 中的 HStack 使多行文本重叠【英文标题】:SwiftUI: HStack in ForEach in VStack makes multi line text overlap 【发布时间】:2021-03-01 23:30:40 【问题描述】:

我在 VStack 内的 ForEach 内的 HStack 内有一个 Text() 视图。文本可以是任意长度的字符串,我无法控制它放在里面。问题是当你运行程序时,VStack 中的视图重叠导致in this jumbled mess

我想做的是有一个根据多行文本视图的高度调整其高度大小的视图,以便视图永远不会重叠,并且始终显示整个字符串。

下面是一些生成相关视图的代码:

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
    

我尝试从文本视图中删除.fixedSize(horizontal: false, vertical: true),但它只会使文本在一行后被截断,这不是我想要的。

如果您需要更多上下文,整个项目位于:https://github.com/LiveTL/apple。我们正在查看 macOS 文件夹中的代码。

【问题讨论】:

【参考方案1】:

您可能会发现使用带有尾随闭包的 List() 会很有用...

List(itemList)  item in 
  Text(item)

这应该可以防止您在尝试显示消息时遇到的问题。有关列表的更多信息,请查看:https://developer.apple.com/documentation/swiftui/list。

您可以在此处的 25:11 看到一个示例:https://developer.apple.com/videos/play/wwdc2019/216/

【讨论】:

谢谢!使用列表可以解决格式问题。但是,我担心性能,并且据我所知,swiftUI 列表的性能远低于 LazyVStack。我会进行一些测试,看看这对我来说是否可行,但我会将此标记为正确答案。 很高兴听到它有效。希望它能满足您的性能要求。

以上是关于SwiftUI:VStack 中 ForEach 中的 HStack 使多行文本重叠的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ForEach 循环中获取计数变量

ForEach 通过多个 TextField 来验证 SwiftUI 中是不是为空

SwiftUI:VStack中的VStack,标签被截断

SwiftUI - 在 VStack 中对齐文本

SwiftUI,删除VStack中视图之间的空间?

SwiftUI 中 ScrollView 中 VStack 中元素的神秘间距或填充