是否可以编写一个函数来组合任意数量的 SwiftUI `ViewModifier's?
Is it possible to write a function to compose an arbitrary number of SwiftUI `ViewModifier's?
考虑以下将填充应用于特定 View
的 ViewModifier
enum Padding {
case small
case medium
case large
}
private struct PaddingModifier: ViewModifier {
var edgeSet: Edge.Set = .all
var size: Padding
func body(content: Content) -> some View {
return content.padding(edgeSet, getSize())
}
func getSize() -> CGFloat {
switch size {
case .small:
return 2
case .medium:
return 8
case .large:
return 16
}
}
}
为了使 ViewModifier
更具可读性,通常我会向 View
添加一个扩展函数
extension View {
func padding(_ size: Padding, _ set: Edge.Set = .all) -> some View {
return modifier(PaddingModifier(edgeSet: set, size: size))
}
}
但是,假设我想将此修饰符应用于 Edge.Set
值的任意列表。我如何编写一个函数,其签名 (Padding, [Edge.Set]) -> some View
对每个 Edge.Set
应用 PaddingModifier
?
我第一个想到的是下面这样的东西,但是Self
不符合some View
extension View {
func padding(_ size: Padding, _ set: Edge.Set = .all) -> some View {
return modifier(PaddingModifier(edgeSet: set, size: size))
}
func padding(_ size: Padding, _ set: [Edge.Set]) -> some View {
set.reduce(self) { [=12=].padding(size, ) }
}
}
Edge.Set
是一个 OptionSet
,因此使用 first 修饰符已经可以编码(类似于内置 .padding([.leading, .trailing], 20)
)
Text("Demo")
.padding(.small, [.leading, .trailing])
看起来padding(_ size: Padding, _ set: [Edge.Set])
想多了。
考虑以下将填充应用于特定 View
ViewModifier
enum Padding {
case small
case medium
case large
}
private struct PaddingModifier: ViewModifier {
var edgeSet: Edge.Set = .all
var size: Padding
func body(content: Content) -> some View {
return content.padding(edgeSet, getSize())
}
func getSize() -> CGFloat {
switch size {
case .small:
return 2
case .medium:
return 8
case .large:
return 16
}
}
}
为了使 ViewModifier
更具可读性,通常我会向 View
extension View {
func padding(_ size: Padding, _ set: Edge.Set = .all) -> some View {
return modifier(PaddingModifier(edgeSet: set, size: size))
}
}
但是,假设我想将此修饰符应用于 Edge.Set
值的任意列表。我如何编写一个函数,其签名 (Padding, [Edge.Set]) -> some View
对每个 Edge.Set
应用 PaddingModifier
?
我第一个想到的是下面这样的东西,但是Self
不符合some View
extension View {
func padding(_ size: Padding, _ set: Edge.Set = .all) -> some View {
return modifier(PaddingModifier(edgeSet: set, size: size))
}
func padding(_ size: Padding, _ set: [Edge.Set]) -> some View {
set.reduce(self) { [=12=].padding(size, ) }
}
}
Edge.Set
是一个 OptionSet
,因此使用 first 修饰符已经可以编码(类似于内置 .padding([.leading, .trailing], 20)
)
Text("Demo")
.padding(.small, [.leading, .trailing])
看起来padding(_ size: Padding, _ set: [Edge.Set])
想多了。