【问题标题】:Multiline text truncated in ScrollViewScrollView 中的多行文本被截断
【发布时间】:2021-05-12 13:28:51
【问题描述】:

ScrollView 中的多行文本有一个相当特殊的问题。我在 ScrollView 中有一个 LazyVStack 并在此堆栈中有 SomeRow(见下文)视图。 我在这个 SomeRow 视图中有一个很长的多行描述,SwiftUI 总是会中断。

我已经尝试了所有here 的解决方案,但它们要么破坏了布局,要么不起作用,要么直接导致应用崩溃。

目前的情况:

我尝试将复制代码减少到最低限度,但不幸的是它仍然很长,因为我想保留我想要完成的外观。

这里是 SomeListView:

import SwiftUI

struct SomeListView: View {
    
    var body: some View {
        VStack{
            Text("Title")
                .font(.title)
            ScrollView{
                LazyVStack{
                    ForEach(0..<4){_ in
                        SomeRow(entries: EntryContainer(entries:
                            [
                                Entry("DESC\nLONG DESCRIPTION WITH OVERFLOW"),
                                Entry("")
                            ]
                        ))
                        Spacer().frame(height: 5)
                        Divider()
                    }
                }
            }.padding(16)
        }
    }
}

struct SomeListView_Previews: PreviewProvider {
    static var previews: some View {
        SomeListView()
    }
}

SomeRow 视图

import SwiftUI

struct SomeRow: View {
    var entries: [Entry]
    
    var body: some View {
        VStack(alignment: .leading, spacing: 0){
            Text("title").frame(maxWidth: .infinity, alignment: .leading)
            Spacer().frame(height: 5)
            ForEach(entries){entry in
                HStack{
                    VStack{
                        Text("00:00 - 00:00")
                        Spacer()
                    }.frame(minWidth: 110)
                    Divider()
                    VStack{
                        HStack{
                            Text("titleinner")
                            Spacer()
                        }
                        HStack{
                            Text(entry.description ?? "")
                            Spacer()
                            VStack{
                                Spacer()
                                Text("number")
                            }
                        }
                        Spacer()
                    }
                    Spacer()
                }
            }
        }
    }
}

struct SomeRow_Previews: PreviewProvider {
    static var previews: some View {
        SomeRow(entries:
            [
                Entry("DESC\nLONG DESCRIPTION WITH OVERFLOW"),
                Entry("")
            ]
        )
    }
}

入口数据类

import Foundation

class Entry: Identifiable {
    let description: String?

    init(_ description: String? = nil) {
        self.description = description
    }
}

任何解决方法的想法?我假设这只是 SwiftUI 错误,因为如果您为两个条目设置相同的长描述,它会神奇地完全显示两个描述,这对我来说真的没有意义。

当我使用Text(entry.description ?? "").fixedSize(horizontal: false, vertical: true 时,它是这样中断的: (分隔线不再填满整个高度,左列中的时间戳对齐错误)

【问题讨论】:

  • 您尝试将.fixedSize(horizontal: false, vertical: true) 放在哪里?您可能需要将其添加到几个不同的元素中才能获得所需的布局。
  • 我尝试将它添加到 Text(entry.description ?? "")
  • 我添加了一个屏幕截图,当我使用 fixedSize 时它的外观。感谢您抽出宝贵时间发表评论:)
  • 我不认为你可以有一个单独的分隔线,你想要完成的事情。但是,我可以向您展示不影响对齐的代码,但它将使用两条分隔线,如您的屏幕截图所示。

标签: swift swiftui


【解决方案1】:

几乎不可能有一个分隔线并保持与您所寻找的相同的对齐方式。我能得到的最接近的显示在下面的代码中。希望能在一定程度上满足要求。

   import SwiftUI

struct SomeListView: View {
    var obj = [
        Entry("DESC LONG DESCRIPTION WITH OVERFLOW"),
        Entry("")
    ]
    var body: some View {
        
        VStack{
            Text("Title")
                .font(.title)
            ScrollView{
                
                LazyVStack(){
                    ForEach(0..<4){_ in
                        SomeRow(entries: obj)
                        Spacer().frame(height: 5)
                        Divider()
                    }
                }
            }.padding(16)
        }
        
    }
}


class Entry: Identifiable {
    let description: String?
    
    init(_ description: String? = nil) {
        self.description = description
    }
}

struct SomeRow: View {
    var entries: [Entry]
    
    var body: some View {
        
        VStack(alignment: .leading,spacing:7){
            
            Text("title")
            
            ForEach(entries){entry in
                
                HStack(alignment: .top,spacing:15){
                    
                    Text("00:00 - 00:00")
                    Divider()
                    VStack(alignment:.leading, spacing:8){
                        Text("titleinner")
                        HStack(alignment:.lastTextBaseline, spacing:0){
                            Text(entry.description ?? "")
                            Spacer()
                            Text("number")
                        }
                        
                    }
                }.fixedSize(horizontal: false, vertical: true)
            }
        }
    }
}

struct SomeRow_Previews: PreviewProvider {
    static var previews: some View {
        SomeRow(entries:
                    [
                        Entry("DESC\nLONG DESCRIPTION WITH OVERFLOW"),
                        Entry("")
                    ]
        )
    }
}

struct SomeListView_Previews: PreviewProvider {
    static var previews: some View {
        SomeListView()
    }
}

输出-:

【讨论】:

  • 谢谢!这肯定比由 fixedSize hack 导致的不对齐的混乱要好。我现在将实现这一点,也许稍后将描述移动到另一个视图中,当用户按下一行时会弹出该视图。您认为值得将此作为苹果的错误提交吗?我是 iOS 应用程序开发的新手,不太确定这是否可以被视为错误,或者是否值得为错误报告而烦恼。但我觉得不可控和不一致的多行行为绝对不是一个特性。 (或者至少希望如此)
【解决方案2】:

借助the answer from Tushar Sharma 的概念,我能够创建一个显示多行文本并在两个“列”之间有连续分隔符的版本。 唯一的变化是 SomeRow View(与我最初的问题相比):

struct SomeRow: View {
    var entries: [Entry]
    
    var body: some View {
        VStack(alignment: .leading, spacing: 0){
            Text("title").frame(maxWidth: .infinity, alignment: .leading)
            Spacer().frame(height: 5)
            ForEach(entries){entry in
                HStack(alignment: .top){
                    VStack{
                        Text("00:00 - 00:00")
                        Spacer()
                    }.frame(minWidth: 110)
                    Divider()
                    VStack(alignment: .leading){
                        Text("titleinner")
                        HStack(alignment: .lastTextBaseline){
                            Text(entry.description ?? "")
                            Spacer()
                            Text("number")
                        }
                        Spacer()
                    }
                    Spacer()
                }.fixedSize(horizontal: false, vertical: true)
            }
        }
    }
}

基本上使用指定的对齐方式并在整个文本容器上使用 fixedSize 会产生奇迹。 这是它现在的样子:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    相关资源
    最近更新 更多