我尝试在else
方法中设置ifLet
的默认参数,但遇到错误:Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements
。怎么了
extension View {
func ifLet<Value, Then: View, Else: View>(
_ value: Value?,
then: (Value) -> Then,
else: () -> View = { EmptyView() }
) -> _ConditionalContent<Then, Else> {
if let value = value {
return ViewBuilder.buildEither(first: then(value))
} else {
return ViewBuilder.buildEither(second: `else`())
}
}
}
使用:
struct TestView: View {
var test: String?
var body: some View {
Group {
ifLet(test) { Text($0) }
ifLet(test, then: { Text($0) }, else: { Text("Empty") })
}
}
}
最好的解决方案,而不使用将来可能会更改或删除的非官方_ConditionalContent
结帐here
答案 0 :(得分:0)
这是可行的方法。经过测试并可以与Xcode 11.2 / iOS 13.2配合使用。
struct TestingIfLet: View {
var some: String?
var body: some View {
VStack {
ifLet(some, then: {value in Text("Test1 \(value)") })
ifLet(some, then: {value in Text("Test2 \(value)") },
else: { Text("Test3") })
}
}
}
extension View {
func ifLet<Value, Then: View>(
_ value: Value?,
then: (Value) -> Then
) -> _ConditionalContent<Then, EmptyView> {
if let value = value {
return ViewBuilder.buildEither(first: then(value))
} else {
return ViewBuilder.buildEither(second: EmptyView())
}
}
func ifLet<Value, Then: View, Else: View>(
_ value: Value?,
then: (Value) -> Then,
else: () -> Else
) -> _ConditionalContent<Then, Else> {
if let value = value {
return ViewBuilder.buildEither(first: then(value))
} else {
return ViewBuilder.buildEither(second: `else`())
}
}
}