首页 > 解决方案 > 如何自定义 SwiftUI ViewBuilder

问题描述

有一些关于 SwiftUI Builder 的帖子是这样的。这样我就可以嵌入我的内容,例如:

struct Container<Content>: View where Content: View {

  var content: Content

  init(@ViewBuilder content: @escaping () -> Content) {
    self.content = content()
  }

  var body: some View {
    return content
  }
}

struct ContentView: View {
  var body: some View {
    Container() {
      Text("Content 1").tag(0)
      Text("Content 2").tag(1)
    }
  }
}

我想知道我是否没有在 init 中传递 ViewBuilder。相反,我想做类似的事情:

struct ContentView: View {
  var body: some View {
    Container().buildContent {
      Text("Content 1").tag(0)
      Text("Content 2").tag(1)
    }
  }
}

我之所以要这样做是因为我想模仿TabView's tabItem

标签: arraysswiftui

解决方案


您不能让buildContent函数改变Container,但您可以默认使用Container仅出售 an 的a ,并将其用作使用所需内容EmptyView创建新内容的跳板。Container

你可以像这样实现那种 API:

struct Container<Content>: View where Content: View {
    var content: Content

    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }

    var body: some View {
        return content
    }
}

extension Container where Content == EmptyView {
    init() {
        self.content = EmptyView()
    }

    /// Return a new `Container` with the given `Content` builder.
    func buildContent<V : View>(@ViewBuilder content: () -> V) -> Container<V> {
        Container<V>(content: content)
    }
}

struct ContentView: View {
    var body: some View {
        Container().buildContent {
            Text("Content 1").tag(0)
            Text("Content 2").tag(1)
        }
    }
}

推荐阅读