【问题标题】:How to customize the SwiftUI ViewBuilder如何自定义 SwiftUI ViewBuilder
【发布时间】:2019-09-09 05:06:44
【问题描述】:

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

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的tabItem。

【问题讨论】:

    标签: arrays swiftui


    【解决方案1】:

    您不能让buildContent 函数改变Container,但您可以默认拥有一个Container,它只是出售一个EmptyView,并将其用作创建新@987654325 的跳板@你想要的内容。

    你可以像这样实现那种 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)
            }
        }
    }
    

    【讨论】:

    • 在您的示例中不需要@escaping,因为函数content 在构造函数结束之前就在那里被调用。如果您保存它并稍后调用它,您将需要它
    猜你喜欢
    • 1970-01-01
    • 2021-04-26
    • 1970-01-01
    • 2020-06-19
    • 2020-12-28
    • 1970-01-01
    • 2020-05-25
    • 2020-06-09
    • 1970-01-01
    相关资源
    最近更新 更多