从 Xcode 11.4 开始,SwiftUI 不允许switch在 Function builder 块中使用语句,如VStack {},失败并出现一般错误,如Generic parameter 'Content' could not be inferred. 如何switch在 SwiftUI 中使用该语句根据枚举值创建不同的视图?
switch 自 Xcode 12 起支持在 SwiftUI 视图构建器中:
enum Status {
case loggedIn, loggedOut, expired
}
struct SwiftUISwitchView: View {
@State var userStatus: Status = .loggedIn
var body: some View {
VStack {
switch self.userStatus {
case .loggedIn:
Text("Welcome!")
case .loggedOut:
Image(systemName: "person.fill")
case .expired:
Text("Session expired")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于 Xcode 11,您可以使用以下解决方法:
a) 将其包装在Group具有显式返回类型的单个块中 - 如果 switch 语句是函数构建器块中的唯一语句,则允许这样做:
enum Status {
case loggedIn, loggedOut, expired
}
struct SwiftUISwitchView: View {
@State var userStatus: Status = .loggedIn
var body: some View {
VStack {
Group { () -> Text in
switch(self.userStatus) {
case .loggedIn:
return Text("Welcome!")
case .loggedOut:
return Text("Please log in")
case .expired:
return Text("Session expired")
}
}
}
}
}
struct SwitchUsageInSwiftUI_Previews: PreviewProvider {
static var previews: some View {
SwiftUISwitchView()
}
}
Run Code Online (Sandbox Code Playgroud)
备选方案 b) 创建一个单独的函数来根据枚举计算视图:
struct SwiftUISwitchView: View {
@State var userStatus: Status = .loggedIn
// if it's always the same View, you can use some View
func viewFor(status: Status) -> some View {
switch(status) {
case .loggedIn:
return Text("Welcome!")
case .loggedOut:
return Text("Please log in")
case .expired:
return Text("Session expired")
}
}
var body: some View {
VStack {
viewFor(status: userStatus)
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果返回的视图可以有不同的类型,则需要将其包装在 an 中,AnyView因为some View要求返回类型在所有情况下都相同:
// if it's different types, you have to erase to AnyView
func viewForStatusDifferentViews(status: Status) -> AnyView {
switch(status) {
case .loggedIn:
return AnyView(Text("Welcome!"))
case .loggedOut:
return AnyView(Image(systemName: "person.fill"))
case .expired:
return AnyView(Text("Session expired"))
}
}
Run Code Online (Sandbox Code Playgroud)
替代方法 c) 创建一个单独的 View 以通过枚举值计算 View:
// if it's different types, you have to erase to AnyView
func viewForStatusDifferentViews(status: Status) -> AnyView {
switch(status) {
case .loggedIn:
return AnyView(Text("Welcome!"))
case .loggedOut:
return AnyView(Image(systemName: "person.fill"))
case .expired:
return AnyView(Text("Session expired"))
}
}
Run Code Online (Sandbox Code Playgroud)
Github 上的可运行示例代码:SwiftUIPlayground
| 归档时间: |
|
| 查看次数: |
1901 次 |
| 最近记录: |