SwiftUI:在带有 Spacers 的 VStack 中平均分配多个 VStack

Posted

技术标签:

【中文标题】SwiftUI:在带有 Spacers 的 VStack 中平均分配多个 VStack【英文标题】:SwiftUI: Distribute equally multiple VStacks in a VStack with Spacers 【发布时间】:2019-09-24 06:25:28 【问题描述】:

我正在尝试构建一个包含多个 VStack(元素)的 VStack(容器),每个 VStack 都有一个标题和一个文本。元素 VStacks 应该均匀分布,并且在它们之间有一个间隔。

由于某种原因,它最多只能使用 4 个元素 VStack,如果我增加,我会得到一个错误

Failed to build ContentView.swift
Ambiguous reference to member 'buildingBlock()'

这是我的代码:

import SwiftUI

struct ContentView: View 
    var body: some View 

        VStack 
            Spacer()
            VStack 
                Text("Title 1")
                Text("Text 1")
            
            Spacer()
            VStack 
                Text("Title 2")
                Text("Text 2")
            
            Spacer()
            VStack 
                Text("Title 3")
                Text("Text 3")
            
            Spacer()
            VStack 
                Text("Title 4")
                Text("Text 4")
            
            Spacer()
            VStack 
                Text("Title 5")
                Text("Text 5")
            
            Spacer()
            VStack 
                Text("Title 6")
                Text("Text 6")
            
            Spacer()
            VStack 
                Text("Title 7")
                Text("Text 7")
            
            Spacer()
            VStack 
                Text("Title 8")
                Text("Text 8")
            
            Spacer()
            VStack 
                Text("Title 9")
                Text("Text 9")
            
            Spacer()
            VStack 
                Text("Title 10")
                Text("Text 10")
            
            Spacer()'
        
        .background(Color.red)

    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

【问题讨论】:

请使用ForEach pleeeease。 【参考方案1】:

由于 SwiftUI 的实现方式,一个视图最多只能有 10 个直接的、显式的子视图。您的*** VStack 有 21 个直接子视图:10 个子视图 VStacks,以及它们周围的 11 个 Spacers。

有多种解决方法。如果你真的需要一个硬编码的子视图列表,你可以使用Group 让一些子视图间接:

struct ContentView: View 
    var body: some View 

        VStack 
            Group 
                Spacer()
                VStack 
                    Text("Title 1")
                    Text("Text 1")
                
                Spacer()
                VStack 
                    Text("Title 2")
                    Text("Text 2")
                
                Spacer()
                VStack 
                    Text("Title 3")
                    Text("Text 3")
                
            
            Group 
                Spacer()
                VStack 
                    Text("Title 4")
                    Text("Text 4")
                
                Spacer()
                VStack 
                    Text("Title 5")
                    Text("Text 5")
                
                Spacer()
                VStack 
                    Text("Title 6")
                    Text("Text 6")
                
            
            Group 
                Spacer()
                VStack 
                    Text("Title 7")
                    Text("Text 7")
                
                Spacer()
                VStack 
                    Text("Title 8")
                    Text("Text 8")
                
                Spacer()
                VStack 
                    Text("Title 9")
                    Text("Text 9")
                
            
            Spacer()
            VStack 
                Text("Title 10")
                Text("Text 10")
            
            Spacer()
        
        .background(Color.red)
    

这里,*** VStack 有 6 个直接子代:3 个Group、2 个Spacer 和 1 个VStack。每个Group 也有6 个直系子代:3 个VStack 和3 个Spacer。没有任何视图拥有超过 10 个直接子级。

这里更好的方法是使用ForEach 来生成孩子:

struct ContentView: View 
    var body: some View 

        VStack 
            Spacer()
            ForEach(1 ... 10, id: \.self)  i in
                Group 
                    VStack 
                        Text("Title \(i)")
                        Text("Text \(i)")
                    
                    Spacer()
                
            
        
        .background(Color.red)
    

现在***VStack只有两个直接子视图:第一个SpacerForEachForEach 会根据需要多次复制其子视图(Group)。

在这种情况下,我们使用 Group 来允许 Swift 推断 ForEach 主体的类型,因为 ForEach 主体将包含两个语句(VStackSpacer)防止 Swift 推断其类型。

【讨论】:

感谢详细而有趣的回复。您能否再补充一点,为什么 SwiftUI 只允许 10 个直接子视图?我认为这是相当有限的。 我已经解释过了in this answer。搜索“了解”。

以上是关于SwiftUI:在带有 Spacers 的 VStack 中平均分配多个 VStack的主要内容,如果未能解决你的问题,请参考以下文章

带有 VST 效果插件的网络音频播放器?

VST 音频插件如何检测来自 VST 主机的流中断?

VST SDK & VST 模块 SDK

如何响应 SwiftUI 中的视图生命周期事件?

在 Windows 上设置 VST Steinberg SDK

windows下构建vst时如何使用外部dll