我如何在 Swift 5 中使用协议功能参数工作,这些参数使用具有关联类型的协议(即 .pickerStyle())
How do i work in Swift 5 with protocol function parameters that use protocols with associated types (i.e. .pickerStyle())
我正在使用 SwiftUI 并想根据选择器中的项目数设置视图的 pickerStyle。对于一些项目,SegmentedPickerStyle() 是理想的,更多的 WheelPickerStyle() 更好。
}.pickerStyle(productsObserver.product.productFamilies?.count ?? 0 < 5 ? SegmentedPickerStyle() : WheelPickerStyle())
函数签名如下:
func pickerStyle<S>(_ style: S) -> some View where S : PickerStyle
我了解到在函数签名中使用泛型,因为 PickerStyle 使用关联类型。
它不应该是一个如此困难的问题而且可能不是 - 协议应该像这样简单地工作=,但我看不到它。
非常感谢任何帮助!
pickerStyle
是一种泛型方法,它接受符合 PickerStyle
的具体类型(在编译时)。因此,它不能是 SegmentedPickerStyle
或 WheelPickerStyle
(在 运行 时确定) - 它必须是其中之一。
因此,一个建议是创建一个视图修饰符并有条件地应用选择器样式。这里的关键区别在于它 returns 类型为 _ConditionalContent<TrueContent, FalseContent>
.
的条件视图
struct PickerStyleOption<P1: PickerStyle, P2: PickerStyle>: ViewModifier {
let predicate: () -> Bool
let style1: P1
let style2: P2
@ViewBuilder
func body(content: Content) -> some View {
if predicate() {
content
.pickerStyle(style1)
} else {
content
.pickerStyle(style2)
}
}
}
为方便起见,您可以创建一个扩展:
extension View {
func pickerStyleOption<P1: PickerStyle, P2: PickerStyle>(
_ condition: @autoclosure @escaping () -> Bool,
then style1: P1,
else style2: P2) -> some View {
self.modifier(
PickerStyleOption(predicate: condition, style1: style1, style2: style2)
)
}
}
并像这样使用它:
Picker(...) {
...
}
.pickerStyleOption((productsObserver.product.productFamilies?.count ?? 0) < 5,
then: SegmentedPickerStyle(), else: WheelPickerStyle())
我正在使用 SwiftUI 并想根据选择器中的项目数设置视图的 pickerStyle。对于一些项目,SegmentedPickerStyle() 是理想的,更多的 WheelPickerStyle() 更好。
}.pickerStyle(productsObserver.product.productFamilies?.count ?? 0 < 5 ? SegmentedPickerStyle() : WheelPickerStyle())
函数签名如下:
func pickerStyle<S>(_ style: S) -> some View where S : PickerStyle
我了解到在函数签名中使用泛型,因为 PickerStyle 使用关联类型。
它不应该是一个如此困难的问题而且可能不是 - 协议应该像这样简单地工作=,但我看不到它。 非常感谢任何帮助!
pickerStyle
是一种泛型方法,它接受符合 PickerStyle
的具体类型(在编译时)。因此,它不能是 SegmentedPickerStyle
或 WheelPickerStyle
(在 运行 时确定) - 它必须是其中之一。
因此,一个建议是创建一个视图修饰符并有条件地应用选择器样式。这里的关键区别在于它 returns 类型为 _ConditionalContent<TrueContent, FalseContent>
.
struct PickerStyleOption<P1: PickerStyle, P2: PickerStyle>: ViewModifier {
let predicate: () -> Bool
let style1: P1
let style2: P2
@ViewBuilder
func body(content: Content) -> some View {
if predicate() {
content
.pickerStyle(style1)
} else {
content
.pickerStyle(style2)
}
}
}
为方便起见,您可以创建一个扩展:
extension View {
func pickerStyleOption<P1: PickerStyle, P2: PickerStyle>(
_ condition: @autoclosure @escaping () -> Bool,
then style1: P1,
else style2: P2) -> some View {
self.modifier(
PickerStyleOption(predicate: condition, style1: style1, style2: style2)
)
}
}
并像这样使用它:
Picker(...) {
...
}
.pickerStyleOption((productsObserver.product.productFamilies?.count ?? 0) < 5,
then: SegmentedPickerStyle(), else: WheelPickerStyle())