Как SwiftUI динамически добавляет элементы VStack, HStack и List? - PullRequest
1 голос
/ 22 апреля 2020

Взять 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)
}

Я добавил 10 прямоугольников в VStack. Пока что проблем не возникает:  Canvas

Однако я добавляю еще один прямоугольник и сообщаю об ошибке: Дополнительный аргумент в вызове

    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:

    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 может иметь только десять элементов, поэтому я написал функция для динамического увеличения общего количества прямоугольников на основе пользовательского ввода:

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 !!! Сообщить об ошибке: функция объявляет непрозрачный тип возвращаемого значения, но операторы возврата в своем теле не имеют соответствующих базовых типов

Кто-нибудь знает решение?

1 Ответ

1 голос
/ 22 апреля 2020

Самое простое в этом случае - просто использовать стирание типа, как показано ниже (протестировано с 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)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...