Search code examples
if-statementenumsswiftuipicker

Used SwiftUI picker and my MacBook heats up to 50 degrees


As soon as I use a code, my MacBook heats up to 50 degrees. I have 4 Enums that each have a picker, as soon as I put 3 pickers into an if-else statement and then debug, my MacBook heats up so much that I almost do it can not touch anymore. error ->

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

i use the enums with the protocols Int16, Hashable, CaseIterable. i want Int16 for my CoreData Attribut. If i change Int16 to Int then the Code Works.. i Convert in the "Taggs" to int so i can use the else if statemant.

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

I expect to select the Main and then the second picker will show me the selected, as if I would select an automaker and in the second picker come the respective car model.


Solution

  • In beta 5, there is a known problem with ForEach. From the release notes:

    Using a ForEach view with a complex expression in its closure can may result in compiler errors. Workaround: Extract those expressions into their own View types. (53325810)

    Your ForEach views, do not seem too complex, and encapsulating its contents does not solve the problem. However, if you encapsulate the entire pickers works fine. Double check the code, as I may have introduced a typo while encapsulating.

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