在 SwiftUI 视图中使用开关/枚举 [英] Using switch/enums in SwiftUI Views

查看:47
本文介绍了在 SwiftUI 视图中使用开关/枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从 Xcode 11.4 开始,SwiftUI 不允许在诸如 VStack {} 之类的函数构建器块中使用 switch 语句,失败并出现诸如 Generic parameter 之类的一般错误内容'无法推断.如何在 SwiftUI 中使用 switch 语句根据枚举值创建不同的视图?

As of Xcode 11.4, SwiftUI doesn't allow switch statements in Function builder blocks like VStack {}, failing with a generic error like Generic parameter 'Content' could not be inferred. How can the switch statement be used in SwiftUI to create different Views depending on an enum value?

推荐答案

switch 从 Xcode 12 开始支持 SwiftUI 视图构建器:

switch in SwiftUI view builders is supported since Xcode 12:

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")
            }

        }
    }
}

对于 Xcode 11,您可以使用以下解决方法:

For Xcode 11 you can use the following workarounds:

a) 将其包装在具有显式返回类型的单个 Group 块中 - 如果 switch 语句是函数构建器块中的唯一语句,则允许这样做:

a) Wrap it in a single Group block with an explicit return type - this is allowed if the switch statement is the only statement in the function builder block:

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()
    }
}

替代方案 b) 创建一个单独的函数来根据枚举计算视图:

Alternative b) Create a separate function to compute the View based on the enum:

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)
        }
    }
}

如果返回的视图可以有不同的类型,则需要将其包装在一个 AnyView 中,因为 some View 要求在所有情况下返回类型都相同:

If the returned view can have different types, you need to wrap it in an AnyView because some View requires the return type to be the same in all cases:

// 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"))
    }
}

替代方法 c) 创建一个单独的 View 以通过枚举值计算 View:

Alternative c) Create a separate View to compute the View by enum value:

// Alternative: A separate view
struct StatusView: View {
 
    var status : Status
    
    var body: some View {
        switch(status) {
        case .loggedIn:
            return AnyView(Text("Welcome!"))
        case .loggedOut:
            return AnyView(Image(systemName: "person.fill"))
        case .expired:
            return AnyView(Text("Session expired"))
        }
    }
    
}

可在 Github 上运行的示例代码:SwiftUIPlayground

这篇关于在 SwiftUI 视图中使用开关/枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆