Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
633 views
in Technique[技术] by (71.8m points)

swiftui - Are there maximum limits to VStack?

I started with a clean project and added 5 buttons and 5 spacers in a VStack and all is good. When I add the 6th spacer at the bottom, the code suddenly won't compile with the error: "Ambiguous reference to member 'buildBlock()'".

What is causing this error? Is this a bug related to SwiftUI? Or is it a feature? It's not the first time I notice that VStack or HStack is limited in the number of entries, is there some documentation around this?

Not exactly confidence inspiring, should I switch back to UIKit?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

SwiftUI uses ViewBuilder to construct the views that make up many SwiftUI views, like VStack, HStack, List, etc. If you take a look at the ViewBuilder documentation, you'll see that the buildBlock function has many copies, each with a different amount of views as arguments. The function with the most amount of views only takes in 10 views which is why you are seeing the limitation that you observed. A way to work around this is by using Groups:

VStack {
    Group {
        Text("Placeholder 0")
        Text("Placeholder 1")
        Text("Placeholder 2")
        Text("Placeholder 3")
        Text("Placeholder 4")
        Text("Placeholder 5")
        Text("Placeholder 6")
        Text("Placeholder 7")
        Text("Placeholder 8")
        Text("Placeholder 9")
    }
    Group {
        Text("Other Placeholder 10")
        Text("Other Placeholder 11")
        Text("Other Placeholder 12")
        Text("Other Placeholder 13")
        Text("Other Placeholder 14")
        Text("Other Placeholder 15")
        Text("Other Placeholder 16")
        Text("Other Placeholder 17")
        Text("Other Placeholder 18")
        Text("Other Placeholder 19")
    }
}

Although if you want 20 views that are really similar to each other, it is encouraged to use something like a ForEach to avoid making your views too bloated. The above workaround should only be used if the >10 views are truly unique. Even then, a more SwiftUI-y method would be to split up these views into more smaller views:

VStack {
    SingleDigitPlaceholders()
    TeensPlaceholders()
}

struct SingleDigitPlaceholders: View {
    var body: some View {
        ForEach(0..<10) { i in
            Text("Placeholder (i)")
        }
    }
}
struct TeensPlaceholders: View {
    var body: some View {
        ForEach(10..<20) { i in
            Text("Other Placeholder (i)")
        }
    }
}

Of course, in this specific example, you can just have the two ForEachs in the original view, but in more complex cases, the point still stands. For example, in a form with many elements (e.g. in a job application form: first name, last name, address, phone number text fields, education dropdown menus, date fields, etc.) you can still split up one view into smaller components (in the job application example - a personal information view, an educational information view, etc.).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...