我有一个视图,表示一个像这样的单元格中的一行
这很好用,但是三个水平元素(图像,标题/字幕,图像)被硬编码为它们各自的类型。
我希望有一个通用的ThreeItemView
,它可以容纳3个任何类型的Views
并按所示排列它们。这将使我可以将相同的容器布局与其他任何视图类型重用。
我创建了一个包含三个@ViewBuilders
的视图:
import Foundation
import SwiftUI
struct ThreeItemView<Start: View, Main: View, End: View>: View {
let start: () -> Start
let main: () -> Main
let end: () -> End
init(@ViewBuilder start: @escaping() -> Start,
@ViewBuilder main: @escaping() -> Main,
@ViewBuilder end: @escaping() -> End) {
self.start = start
self.main = main
self.end = end
}
var body: some View {
return HStack {
start()
main()
.frame(minWidth: 0, maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
end()
}
.frame(minWidth: 0, maxWidth: .infinity, maxHeight: 60, alignment: .leading)
}
}
struct ThreeItemContainer_Previews: PreviewProvider {
static var previews: some View {
ThreeItemView(start: {
Image(systemName: "envelope.fill")
}, main: {
Text("Main")
}, end: {
Image(systemName: "chevron.right")
})
}
}
这可以按预期工作,但是API有点麻烦。有什么方法可以简化ThreeItemView
的使用?
答案 0 :(得分:2)
如果您的意思是如下所示
ThreeItemView {
Start {
Image(systemName: "envelope.fill")
}
Main {
Text("Main")
}
End {
Image(systemName: "chevron.right")
}
}
然后在下面找到修改您的模块
typealias Start<V> = Group<V> where V:View
typealias Main<V> = Group<V> where V:View
typealias End<V> = Group<V> where V:View
struct ThreeItemView<V1, V2, V3>: View where V1: View, V2: View, V3: View {
private let content: () -> TupleView<(Start<V1>, Main<V2>, End<V3>)>
init(@ViewBuilder _ content: @escaping () -> TupleView<(Start<V1>, Main<V2>, End<V3>)>) {
self.content = content
}
var body: some View {
let (start, main, end) = self.content().value
return HStack {
start
main
.frame(minWidth: 0, maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
end
}
.frame(minWidth: 0, maxWidth: .infinity, maxHeight: 60, alignment: .leading)
}
}
struct ThreeItemContainer_Previews: PreviewProvider {
static var previews: some View {
ThreeItemView {
Start {
Image(systemName: "envelope.fill")
}
Main {
Text("Main")
}
End {
Image(systemName: "chevron.right")
}
}
}
}