如何更改 SwiftUI 列表中文本数量的最大限制?

Posted

技术标签:

【中文标题】如何更改 SwiftUI 列表中文本数量的最大限制?【英文标题】:How to change max limitation of Text amount in SwiftUI List? 【发布时间】:2019-10-18 05:04:44 【问题描述】:

我在创建一个新的空白项目时发现了一个问题,列表中最多只有 10 个文本元素,否则会导致编译错误,我可以在任何地方编辑限制吗?

struct ContentView: View 
    var body: some View 
        List 
            Text("Line 1")
            Text("Line 2")
            Text("Line 3")
            Text("Line 4")
            Text("Line 5")
            Text("Line 6")
            Text("Line 7")
            Text("Line 8")
            Text("Line 9")
            Text("Line 10")

            // Uncomment this line will cause Complie Error
            // Text("Line 11")
        
    

我尝试添加一个模型

class MyModel: ObservableObject 

    @Published var items: [String] = [
        "line 1",
        "line 2",
        "line 3",
        "line 4",
        "line 5",
        "line 6",
        "line 7",
        "line 8",
        "line 9",
        "line 10",
        "line 11",
    ]

按模型数据显示列表,显示修正

@ObservedObject var model = MyModel()

var body: some View 

    List 
        ForEach(model.items.indices)  index in
            Text(self.model.items[index])
        
    

那么,问题不在于 List,是 Function Builder 吗?

更新了一个新方法,使用Group,对于VStack,是可以的,但是对于List,它会显示11行,并且每一行都与“Line 11”重叠

List 
    Group 
        Text("Line 1")
        Text("Line 2")
        Text("Line 3")
        Text("Line 4")
        Text("Line 5")
        Text("Line 6")
        Text("Line 7")
        Text("Line 8")
        Text("Line 9")
        Text("Line 10")
    

    Group 
        Text("Line 11")
    

【问题讨论】:

您必须将它们分成组。 找到了一篇关于此的文章hackingwithswift.com/quick-start/swiftui/… 说:“SwiftUI 中的所有容器必须返回不超过 10 个子项,这对于大多数用途来说通常是可以的。但是,如果您需要有超过 10 个视图, 如果你需要从你的 body 属性返回多个视图,或者如果你需要返回几种不同类型的视图,你应该使用这样的组" 这里有详细描述hackingwithswift.com/quick-start/swiftui/… 但是如果将VStack替换为List,文本会重叠。 【参考方案1】:

那么,问题不在于 List,是 Function Builder 吗?

是的,没错。问题与@ViewBuilder 闭包的实现方式密切相关。目前,这些闭包不能采用可变参数。因此,他们以这种方式实现了 10 种方法(您可以在 xCode 中查看这些接口):

/// Builds an empty view from an block containing no statements, ` `.
public static func buildBlock() -> EmptyView

/// Passes a single view written as a child view (e..g, ` Text("Hello") `) through
/// unmodified.
public static func buildBlock<Content>(_ content: Content) -> Content where Content : View

public static func buildBlock<C0, C1>(_ c0: C0, _ c1: C1) -> TupleView<(C0, C1)> where C0 : View, C1 : View

public static func buildBlock<C0, C1, C2>(_ c0: C0, _ c1: C1, _ c2: C2) -> TupleView<(C0, C1, C2)> where C0 : View, C1 : View, C2 : View

public static func buildBlock<C0, C1, C2, C3>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3) -> TupleView<(C0, C1, C2, C3)> where C0 : View, C1 : View, C2 : View, C3 : View

public static func buildBlock<C0, C1, C2, C3, C4>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4) -> TupleView<(C0, C1, C2, C3, C4)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View

public static func buildBlock<C0, C1, C2, C3, C4, C5>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5) -> TupleView<(C0, C1, C2, C3, C4, C5)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View

public static func buildBlock<C0, C1, C2, C3, C4, C5, C6>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6) -> TupleView<(C0, C1, C2, C3, C4, C5, C6)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View, C6 : View

public static func buildBlock<C0, C1, C2, C3, C4, C5, C6, C7>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6, _ c7: C7) -> TupleView<(C0, C1, C2, C3, C4, C5, C6, C7)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View, C6 : View, C7 : View

public static func buildBlock<C0, C1, C2, C3, C4, C5, C6, C7, C8>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6, _ c7: C7, _ c8: C8) -> TupleView<(C0, C1, C2, C3, C4, C5, C6, C7, C8)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View, C6 : View, C7 : View, C8 : View

public static func buildBlock<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6, _ c7: C7, _ c8: C8, _ c9: C9) -> TupleView<(C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View, C6 : View, C7 : View, C8 : View, C9 : View

如您所见,@ViewBuilder 闭包可以接受的最大参数数是 10。

解决方案取决于您的需求,如果闭包内的视图基本上是相同的视图,但内容不同,您应该在 List 内使用 ForEach(这正是针对此类情况的意思):

struct ContentView: View 
    var body: some View 
        List 
            ForEach  val in
                //your view
            
        
    

如果视图确实超过 10 个不同的视图,您必须依靠 Group 视图将视图拆分为多个组:

struct ContentView: View 
    var body: some View 
        ScrollView 
            Group 
                //10 views
            

            Group 
                //10 views
            
        
    

【讨论】:

以上是关于如何更改 SwiftUI 列表中文本数量的最大限制?的主要内容,如果未能解决你的问题,请参考以下文章

限制列表的对象数量 - SwiftUi

根据最大宽度限制 SwiftUI HStack 中的视图数量

根据数组中的重复模式更改 SwiftUI 列表中文本字段的第二次出现

文本字段背景图像 Aspect fit 限制了 swiftUI 中 iPad 的宽度

Dynamics CRM 数据数量限制更改

SwiftUI:如何在搜索栏的文本更改时触发 api 调用以检索数据源