Как использовать @ViewBuilder в swiftUI?

Это происходит по трем причинам:

  • Возврат другого типа представления с условиями if / switch. (iOS 14 также поддерживает)
  • Создание нескольких представлений без контейнера
  • Забудьте вернуть взгляд

1. Возврат другого типа представления с условиями if / switch:

В следующем примере вы можете увидеть, что условие «если» возвращает два типа представления. Дерево просмотра допускает аналогичный вид представления с «if / else».

struct ViewBuilderDemo: View {
    @State var shouldShowErrorView = true
    var body: some View {
       if shouldShowErrorView {
            Button("Retry") { shouldShowErrorView = false }
        } else {
            Text("Success")
        }
     }
}
//view in if and else should be same 
//or else opaque return type error

Исправление с помощью functionBuilder под названием ViewBuilder:

ViewBuilder поддерживает « buildEither ». buildEither принимает любой и еще шаблон содержимого. Чтобы решить эту проблему, вы можете напрямую добавить свойство @ ViewBuilder в представление , как показано ниже:

struct ViewBuilderDemo: View {
    @State var shouldShowErrorView = true
    @ViewBuilder var body: some View { //No error 
       if shouldShowErrorView {
            Button("Retry") { shouldShowErrorView = false }
        } else {
            Text("Success")
        }
     }
}

Исправление путем обертывания представлений if / else в AnyView: т.е. создание аналогичного типа

struct ViewBuilderDemo: View {
   @State var shouldShowErrorView = true
   var body: some View {
      if shouldShowErrorView {
           return AnyView(Button("Retry") { shouldShowErrorView = false })
      } else {
         return AnyView(Text("Success"))
      }
   }
}

2. Создание нескольких представлений без контейнера

struct ViewBuilderDemo: View {
   @State var shouldShowErrorView = true
   var body: some View {
     Button("Retry") { shouldShowErrorView = false }
     Text("Success")
   }
}
//Error

Исправление с помощью functionBuilder под названием ViewBuilder:

Поскольку ViewBuilder также имеет кортежи BuildBlock, он может группировать представления

struct ViewBuilderDemo: View {
   @State var shouldShowErrorView = true
   @ViewBuilder var body: some View { //No error
     Button("Retry") { shouldShowErrorView = false }
     Text("Success")
   }
}

Или группировать через групповой виджет:

struct ViewBuilderDemo: View {
   @State var shouldShowErrorView = true
   var body: some View { 
      Group { //No error
        Button("Retry") { shouldShowErrorView = false }
        Text("Success") 
      }
    }
}

3. Забудьте вернуть представление

Обычно это происходит, когда у вас есть какая-то локальная переменная в представлении, а тело представления не может автоматически определять представление возврата:

struct ViewBuilderDemo: View {
   @State var shouldShowErrorView = true
   var body: some View {
       let text = "Success"
       Text(text)
   }
}
//Error

Просто добавьте возврат к окончательному виду:

struct ViewBuilderDemo: View {
   @State var shouldShowErrorView = true
   var body: some View {
       let text = "Success"
       return Text(text)
   }
}

Выполнено