SwiftUI 如何动态添加 VStack、HStack、List 的元素? [英] How does SwiftUI dynamically add elements of VStack, HStack, and List?

查看:25
本文介绍了SwiftUI 如何动态添加 VStack、HStack、List 的元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以VStack为例:

VStack {
    Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
    Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
    Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
    Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
    Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
    Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
    Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
    Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
    Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
    Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
}

我向 VStack 添加了 10 个矩形.到目前为止似乎没有问题:画布

I added 10 Rectangles to VStack. So far there seems to be no problem:  Canvas

然而我添加了另一个矩形然后报错:Extra argument in call

However I add another Rectangles then report an error: Extra argument in call

    VStack {
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
    }

这意味着 VStack、HStack 和 List 的构造函数只能接受 10 个参数,所以我将策略更改为使用嵌套 VStack:

This means that the constructors of VStack, HStack and List can only accept 10 arguments, so I changed the strategy to use nested VStack:

    VStack {
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        VStack {
            Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
            Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
        }
    }

这样可以突破VStack只能有10个元素的限制,所以我写了一个函数,根据用户输入动态增加Rectangle的总数:

This can break through the limitation that VStack can only have ten elements, so I wrote a function to dynamically increased the total number of Rectangles based on user input:

private func createRectangles(rectCount: UInt) -> some View {
    func createRectangles(_ i: UInt) -> some View {
        if i <= rectCount {
            return VStack {
                Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
                createRectangles(i + 1)
            }
        } else {
            return VStack {
                Rectangle()
            }
        }
    }
    return createRectangles(1)
}

反对!!!报错:函数声明了一个不透明的返回类型,但其主体中的返回语句没有匹配的底层类型

Opos!!! Report an error: Function declares an opaque return type, but the return statements in its body do not have matching underlying types

有人知道解决办法吗?

推荐答案

在这种情况下最简单的就是使用类型擦除,如下所示(使用 Xcode 11.4/iOS 13.4 测试)

The simplest in this case is just to use type erasure, like below (tested with Xcode 11.4 / iOS 13.4)

private func createRectangles(rectCount: UInt) -> some View {
    func createRectangles(_ i: UInt) -> some View {
        if i <= rectCount {
            return AnyView(VStack {
                Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
                createRectangles(i + 1)
            })
        } else {
            return AnyView(VStack {
                Rectangle()
            })
        }
    }
    return createRectangles(1)
}

这篇关于SwiftUI 如何动态添加 VStack、HStack、List 的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆