如何定义一个接受任意数据元素并产生“某些”视图的闭包?

问题描述 投票:1回答:1

我正在构建一个显示字符串集合的自定义视图,但想对其进行扩展以接受一个闭包,该闭包将使这些字符串中的每个字符串呈现不同的外观,可能不作为Text视图。例如,这是我的原始代码:

struct MyCollectionView : View {
  var data : [String]
  var body : some View {
    ZStack {
      ForEach(0..<data.count, id: \.self) { string in
        Text(string) // <- will try to invoke the closure here
      }
    }
  }
}

但是现在我想注入一个“ renderer”闭包,它将接受一个字符串并产生一个视图,如下所示:

struct MyCollectionView : View {
  typealias CellRenderer = (String)->View
  var cellRenderer : CellRenderer = { string in // compiler error on CellRenderer: "Protocol 'View' 
    // can only be used as a generic constraint because it has Self or associated type requirements"
    Text(string)
  } // default implementation
  var data : [String]
  var body : some View {
    ZStack {
      ForEach(0..<data.count, id: \.self) { string in
        self.cellRenderer(string) // <- trying to invoke the cell renderer
      }
    }
  }
}

我如何声明这种关闭?也许它不应该是一个闭包,而是一个在给定字符串的情况下会产生some View的对象。

swiftui
1个回答
1
投票
这里是可能的方法之一。适用于Xcode 11.2,iOS 13.2。

struct MyCollectionView<Data, Cell>: View where Data: Hashable, Cell: View { typealias CellRenderer = (Data) -> Cell var data : [Data] var cellRenderer : CellRenderer init(_ data: [Data], @ViewBuilder cellRenderer: @escaping CellRenderer) { self.data = data self.cellRenderer = cellRenderer } var body : some View { ZStack { ForEach(data, id: \.self) { value in self.cellRenderer(value) } } } } struct MyCollectionView_Previews: PreviewProvider { static var previews: some View { MyCollectionView(["one", "two"]) { value in Text(value) } } }

© www.soinside.com 2019 - 2024. All rights reserved.