ScrollView 中的多行文本被截断

Posted

技术标签:

【中文标题】ScrollView 中的多行文本被截断【英文标题】:Multiline text truncated in ScrollView 【发布时间】: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 时它的外观。感谢您抽出宝贵时间发表评论:) 我不认为你可以有一个单独的分隔线,你想要完成的事情。但是,我可以向您展示不影响对齐的代码,但它将使用两条分隔线,如您的屏幕截图所示。 【参考方案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 会产生奇迹。 这是它现在的样子:

【讨论】:

以上是关于ScrollView 中的多行文本被截断的主要内容,如果未能解决你的问题,请参考以下文章

TextLabel 在 ScrollView 中被截断

UIStackView 和截断的多行 UILabel

具有多行文本的 Scrollview 中的 Listview

反应原生,当我设置图像样式时文本被截断

ScrollView 文本对齐 SwiftUI

iOS drawInRect:属性使用多行执行文本截断