Существуют ли максимальные ограничения для VStack? - PullRequest
1 голос
/ 15 октября 2019

Я начал с чистого проекта и добавил 5 кнопок и 5 проставок в VStack, и все хорошо. Когда я добавляю 6-ю проставку внизу, код неожиданно не скомпилируется с ошибкой: «Неоднозначная ссылка на член 'buildBlock ()'".

Что вызывает эту ошибку? Это ошибка, связанная с SwiftUI? Или это особенность? Это не первый раз, когда я замечаю, что VStack или HStack ограничены в количестве записей, есть ли какая-то документация вокруг этого?

Не совсем внушает доверие, я должен вернуться к UIKit?

Ответы [ 2 ]

0 голосов
/ 15 октября 2019

SwiftUI использует ViewBuilder для построения представлений, которые составляют множество представлений SwiftUI, например VStack, HStack, List и т. Д. Если вы посмотрите на документацию ViewBuilder ,вы увидите, что функция buildBlock имеет много копий, каждое из которых имеет разное количество представлений в качестве аргументов. Функция с наибольшим количеством просмотров занимает всего 10 просмотров, поэтому вы видите ограничение, которое вы наблюдали. Чтобы обойти это, используйте Group s:

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")
    }
}

Хотя, если вы хотите, чтобы 20 видов действительно были похожи друг на друга, рекомендуется использовать что-то вроде ForEach, чтобы избежатьделая ваши взгляды слишком раздутыми. Описанный выше обходной путь следует использовать только в том случае, если> 10 представлений действительно уникальны. Даже тогда более SwiftUI-y-метод будет разделять эти представления на более мелкие представления:

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)")
        }
    }
}

Конечно, в этом конкретном примере вы можете просто иметь два ForEach впервоначальный вид, но в более сложных случаях точка зрения остается неизменной. Например, в форме со многими элементами (например, в форме заявления о приеме на работу: имя, фамилия, адрес, текстовые поля телефонного номера, раскрывающиеся меню образования, поля даты и т. Д.) Вы все равно можете разделить один вид на более мелкие компоненты. (в примере заявления о приеме на работу - просмотр личной информации, просмотр образовательной информации и т. д.).

0 голосов
/ 15 октября 2019

В вашем VStackZStack, HStack и т. Д.) Может быть не более 10 детей. Это строго связано с их реализацией и реализацией замыканий @ViewBuilder в целом. Посмотрите на интерфейсы здесь ниже (вы можете найти их через xCode, я немного упростил их, чтобы они были более читабельными):

public struct ViewBuilder {    
    /// 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
}

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

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

extension ViewBuilder {
    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
}

extension ViewBuilder {
    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
}

extension ViewBuilder {
    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
}

extension ViewBuilder {
    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
}

extension ViewBuilder {
    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
}

extension ViewBuilder {
    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
}

extension ViewBuilder {
    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
}

Как вы можете видеть, вы можете создавать такие виды с максимум 10дети. Каждый метод buildBlock принимает точное количество просмотров в качестве параметров. Это связано с тем, что @ViewBuilder замыкания, по крайней мере на данный момент, не поддерживают переменные аргументы.

Обходной путь может быть:

struct ContentView: View {
    var body: some View {
        VStack {
            Group {
                //10 views here
            }

            Group {
                //10 views here
            }
        }
    }
}
...