【问题标题】:SwiftUI doesn't like switch?SwiftUI 不喜欢 switch?
【发布时间】:2020-05-08 07:19:59
【问题描述】:

尝试关注this discussion,我执行了Yurii Kotov的建议:

struct ContentView: View {

@State private var index = 0

@ViewBuilder
 var body: some View {
   if index == 0 {
       MainView()
   } else {
       LoginView()
   }
}

它工作正常。但如果我尝试改用 switch 语句:

    switch  index {
        case 0: MainView()
        case 1: LoginView()
        default:
            print("# error in switch")
        }

什么都没有发生。没有错误警报,但也根本没有结果。有人可以帮忙吗?

【问题讨论】:

  • 您的 switch 语句与 if 的作用不同。如果你写一个等效的 switch 语句,那么它应该可以工作。
  • 好的,Sweeper,但它有什么问题?
  • 想一想index 为2 的情况,如果是怎么办?交换机会做什么?
  • 这是一个有趣的讨论,但我已经将索引定义为 0,所以切换到 1000 发生的事情应该没有意义。它应该匹配 0 的情况。恕我直言。
  • 每当@State 更改时,您的视图就会更新,这意味着body 中的所有内容都会重新评估。

标签: swift if-statement switch-statement swiftui


【解决方案1】:

我在默认情况下遇到了问题,我想要一个“中断”类型的情况以使开关详尽无遗。 SwiftUI 需要某种类型的视图,我发现

EmptyView() 解决了这个问题。

在这里EmptyView Discussion 也注意到你“必须返回一些东西”

struct FigureListMenuItems: View {
    var showContextType: ShowContextEnum
    @Binding var isFavoriteSeries: Bool?

    var body: some View {
    
        Menu {
            switch showContextType {
            case .series:
                Button(action: { toggleFavoriteSeries() }) {
                    isFavoriteSeries! ?
                    Label("Favorite Series?", systemImage: "star.fill")
                        .foregroundColor(.yellow)
                    :
                    Label("Favorite Series?", systemImage: "star")
                        .foregroundColor(.yellow)
                }
            default: // <-- can use EmptyView() in this default too if you want
                Button(action: {}) {
                    Text("No menu items")
                }
            }
        } label: {
            switch showContextType {
            case .series:
                isFavoriteSeries! ?
                Image(systemName: "star.fill")
                    .foregroundColor(.yellow)
                :
                Image(systemName: "star")
                    .foregroundColor(.yellow)
            default:
                EmptyView()
            }
            Label("Menu", systemImage: "ellipsis.circle")
        }
    }

    private func toggleFavoriteSeries() {
        isFavoriteSeries?.toggle()
    }
}

开关枚举

enum ShowContextEnum: Int {
    case series = 1
    case whatIsNew = 2
    case allFigures = 3
}

【讨论】:

    【解决方案2】:

    正如@Sweeper 所说:您的if...elseswitch...case 语句不相等。主要思想是:body 只是View protocol 的一个计算变量,它应该返回某种它的类型。当然,您可以使用 switch...case 语句来做到这一点。在您的代码中,sn-p 错误出现在default 语句中:body cannot return() -&gt; Void,只有some View。所以你的代码应该是这样的:

    struct ViewWithSwitchStatements: View {
    
        @State var option = 0
    
        var body: some View {
    
            switch option {
            case 1:
                return AnyView(Text("Option 1"))
            case 2:
                return AnyView(Text("Option 2"))
            default:
                return AnyView(Text("Wrong option!"))
            }
    
        }
    }
    

    但是您不能将其放入 VStack 或其他内容中,例如 if...else 语句。

    【讨论】:

    • 另外,请注意避免从 ViewBuilders 返回 Opaque 类型(不要包装在 AnyView 中),因为它隐藏了所有类型信息,编译器无法优化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 2022-08-03
    • 2022-12-13
    • 1970-01-01
    • 2018-06-26
    相关资源
    最近更新 更多