首页 > 解决方案 > 使用 SwiftUI 选择器,我的 MacBook 加热到 50 度

问题描述

一旦我使用代码,我的 MacBook 就会升温到 50 度。我有 4 个枚举,每个都有一个选择器,只要我将 3 个选择器放入 if-else 语句然后调试,我的 MacBook 就会发热,我几乎不能再触摸它了。错误->

编译器无法在合理的时间内对该表达式进行类型检查;尝试将表达式分解为不同的子表达式

我将枚举与 Int16、Hashable、CaseIterable 协议一起使用。我想要 Int16 作为我的 CoreData 属性。如果我将 Int16 更改为 Int,则代码可以工作。我将“标签”中的转换为 int,这样我就可以使用 else if 语句。

Import SwiftUI
struct EnumsInEnums: View {
          @State  var pickMain = 0
          @State  var pickA = 0
          @State  var pickB = 0
          @State  var pickC = 0

enum MainEnum :  Int16, Hashable, CaseIterable
        {
        case AEnum
        case BEnum
        case CEnum
        var name: String { return "\(self)" }
        }
enum AEnum :  Int16, Hashable, CaseIterable
        {
        case Aa
        case Ba
        case Ca
        var name: String { return "\(self)" }
        }
enum BEnum :  Int16, Hashable, CaseIterable
        {
        case Ab
        case Bb
        case Cb
        var name: String { return "\(self)" }
        }
enum CEnum :  Int16, Hashable, CaseIterable
        {
        case Ac
        case Bc
        case Cc
        var name: String { return "\(self)" }
}
var body: some View {
 NavigationView {
  Form {
   Section {

   Picker(selection: $pickMain, label: Text("Pick \(pickMain)")) {
                 ForEach(MainEnum.allCases, id: \.self){ x in
                 Text("\(x.name)").tag(Int(x.rawValue))
                 }
                    }
    if pickMain == 0 {
       Picker(selection: $pickA, label: Text("Pick \(pickA)")) {
                  ForEach(AEnum.allCases, id: \.self){ x in
                  Text("\(x.name)").tag(Int(x.rawValue))
                  }
             }
       } else if pickMain == 1 {
       Picker(selection: $pickB, label: Text("Pick \(pickB)")) {
                  ForEach(BEnum.allCases, id: \.self){ x in
                  Text("\(x.name)").tag(Int(x.rawValue))
                  }
             }
       } else if pickMain == 2 {
       Picker(selection: $pickC, label: Text("Pick \(pickC)")) {
                  ForEach(CEnum.allCases, id: \.self){ x in
                  Text("\(x.name)").tag(Int(x.rawValue))
                  }
            }
      }
     }
    }
   }
  }
 }

我希望选择 Main,然后第二个选择器将向我显示所选的,就好像我会选择一个汽车制造商,然后在第二个选择器中显示相应的汽车型号。

标签: if-statementenumsswiftuipicker

解决方案


在 beta 5 中,ForEach 存在一个已知问题。从发行说明:

在其闭包中使用带有复杂表达式的 ForEach 视图可能会导致编译器错误。解决方法:将这些表达式提取到它们自己的视图类型中。(53325810)

您的 ForEach 视图似乎并不太复杂,封装其内容并不能解决问题。但是,如果您封装整个选择器工作正常。仔细检查代码,因为我可能在封装时引入了一个错字。

import SwiftUI

struct ContentView: View {
    var body: some View {
        EnumsInEnums()
    }
}

struct EnumsInEnums: View {
    @State  var pickMain = 0
    @State  var pickA = 0
    @State  var pickB = 0
    @State  var pickC = 0

    enum MainEnum :  Int16, Hashable, CaseIterable
    {
        case AEnum
        case BEnum
        case CEnum
        var name: String { return "\(self)" }
    }
    enum AEnum :  Int16, Hashable, CaseIterable
    {
        case Aa
        case Ba
        case Ca
        var name: String { return "\(self)" }
    }
    enum BEnum :  Int16, Hashable, CaseIterable
    {
        case Ab
        case Bb
        case Cb
        var name: String { return "\(self)" }
    }
    enum CEnum :  Int16, Hashable, CaseIterable
    {
        case Ac
        case Bc
        case Cc
        var name: String { return "\(self)" }
    }

    var body: some View {
        NavigationView {
            Form {
                Section {

                    PickerMain(pickMain: $pickMain)

                    if pickMain == 0 {
                        PickerA(pickA: $pickA)
                    }
                    else if pickMain == 1 {
                        PickerB(pickB: $pickB)
                    } else if pickMain == 2 {
                        PickerC(pickC: $pickC)

                    }
                }
            }
        }
    }

    struct PickerMain: View {
        @Binding var pickMain: Int

        var body: some View {
            Picker(selection: $pickMain, label: Text("Pick \(pickMain)")) {
                ForEach(MainEnum.allCases, id: \.self){ x in
                    Text("\(x.name)").tag(Int(x.rawValue))
                }
            }
        }
    }

    struct PickerA: View {
        @Binding var pickA: Int

        var body: some View {
            Picker(selection: $pickA, label: Text("Pick \(pickA)")) {
                ForEach(AEnum.allCases, id: \.self){ x in
                    Text("\(x.name)").tag(Int(x.rawValue))
                }
            }
        }
    }

    struct PickerB: View {
        @Binding var pickB: Int

        var body: some View {
            Picker(selection: $pickB, label: Text("Pick \(pickB)")) {
                ForEach(BEnum.allCases, id: \.self){ x in
                    Text("\(x.name)").tag(Int(x.rawValue))
                }
            }
        }
    }

    struct PickerC: View {
        @Binding var pickC: Int

        var body: some View {
            Picker(selection: $pickC, label: Text("Pick \(pickC)")) {
                ForEach(CEnum.allCases, id: \.self){ x in
                    Text("\(x.name)").tag(Int(x.rawValue))
                }
            }
        }
    }
}

推荐阅读