您可以使用
View Extractor
获取的视图
ViewBuilder
。请注意,这使用了不稳定的API。
以下是一个示例:
struct ContentView: View {
@State private var selectionIndex: Int = 2
var body: some View {
CustomPicker(selection: $selectionIndex) {
Text("1").id(1)
Text("2").id(2)
}
}
}
struct CustomPicker<Content: View, Selection: Hashable>: View {
let content: Content
@Binding var selection: Selection
init(selection: Binding<Selection>, @ViewBuilder content: () -> Content) {
self.content = content()
self._selection = selection
}
var body: some View {
HStack {
ExtractMulti(content) { views in
ForEach(views) { view in
let tag = view.id(as: Selection.self)
Button {
if let tag {
selection = tag
}
} label: { view }
.foregroundStyle(selection == tag ? .blue : .black)
}
}
}
}
}
注意,我在这里使用
id
而不是
tag
识别视图,因为这样更方便。的视图特征键
标签
是内部类型,因此很难访问它。您可以尝试找到镜像路径,但只需编写自己的视图特征键可能会更容易:
struct CustomTagTrait<V: Hashable>: _ViewTraitKey {
static var defaultValue: V? { nil }
}
extension View {
func customTag<V: Hashable>(_ tag: V) -> some View {
_trait(CustomTagTrait<V>.self, tag)
}
}
...
CustomPicker(selection: $selectionIndex) {
Text("1").customTag(1)
Text("2").customTag(2)
}
然后您可以通过以下方式获取标签:
let tag = view[CustomTagTrait<Selection>.self]