SwiftUI: struct View против @ViewBuilder

Sep 10 2020

Если я хочу отобразить список элементов в SwiftUI, я мог бы сделать что-то вроде этого (используя XCode 12):

struct MyView: View {
    let texts: [String]
    var body: some View {
        ScrollView {
            LazyVStack {
                ForEach(texts.indices, id: \.self) { index in
                    MyRow(label: texts[index])
                }
            }
        }
    }

    struct MyRow: View {
        let label: String
        var body: some View {
            Text(label).font(.title3).padding()
        }
    }
}

Вместо структуры MyRowможет быть функцией, что делает код более лаконичным и функциональным:

struct MyView: View {
    let texts: [String]
    var body: some View {
        ScrollView {
            LazyVStack {
                ForEach(texts.indices, id: \.self) { index in
                    MyRow(label: texts[index])
                }
            }
        }
    }

    @ViewBuilder func MyRow(label: String) -> some View {
        Text(label).font(.title3).padding()
    }
}

Я хотел бы понять разницу между двумя подходами. Есть ли случаи, когда вы бы предпочли одно другому?

Первое, что приходит в голову, это то, что у вас не может быть @Stateсвойств с функциями, а это означает, что вам нужно использовать structподход, если вашему представлению требуется состояние.

Это все? Есть ли случаи, когда один подход лучше с точки зрения оптимизации? Отладка? Функции? Переносимость?

Ответы

ChristophePrat Sep 09 2020 at 23:35

@ViewBuilderв основном используется для условного рендеринга представлений без использования парсеров, таких как AnyView(YourView). Процитируем веб-сайт разработчика Apple : «Клиенты этой функции могут использовать замыкания с несколькими операторами для предоставления нескольких дочерних представлений». Например, если вы хотите отобразить представление в зависимости от переменной, то есть визуализировать View1, если определенная переменная истинна, и View2, если она ложна.