Unable to Type-Check in Reasonable Amount of Time

Hello again! I was trying to open and render my app today when a strange error showed on the body of the view. The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions. Now, I have no idea what a sub-expression is, but I shouldn’t have to do anything because this code was working literally minutes ago.

I have tried re-starting both XCode and my computer but nothing seems to happen. Does anyone know why this is occurring?

Full View Code
//
//  ContentView.swift
//  Scam Inspector
//
//  Created by Hendric Voris on 4/18/21.
//

import SwiftUI

struct ContentView: View {
    
    @State var Percent = 0
    @State var percentText = ""
    @State var nextButtonText = "Start"
    @State var nextButtonImage = "play.fill"
    @State var QuestionText = ""
    @State var QuestionNum = 0
    @State var numTypos = 0.0
    @State var stepNum = 0
    @State var ageNum = 0
    @State var temporaryTypoPercent = 0.0
    @State var userName = ""
    
    //Generic menu variables
    
    @State var menuTypoTitle = ""
    @State var menuAgeTitle = ""
    
    //Typo variables
    
    @State var OneToFive = ""
    @State var SixToTen = ""
    @State var Eleven = ""
    @State var TwentyUp = ""
    
    // Age variables
    
    @State var highAgeVar = ""
    @State var mediumAgeVar = ""
    @State var lowAgeVar = ""
    
    
    // Functions
    
    func removeAllText() {
        menuTypoTitle = ""
        menuAgeTitle = ""
        OneToFive = ""
        SixToTen = ""
        Eleven = ""
        TwentyUp = ""
    }
    
    // Functions for age menu
    
    func calculateAgePercent() {
        let double = Double(ageNum)
        let agePercent = double * 1.5
        temporaryTypoPercent = agePercent
    }
    
    func LowAge() {
        numTypos = 6
        calculateAgePercent()
    }
    
    func mediumAge() {
        ageNum = Int(1.5)
        let agePercent = ageNum * Int(1.5)
        Percent += Int(agePercent)
        percentText = String(Percent) + "%"
    }
    
    func highAge() {
        ageNum = 1
        let agePercent = ageNum * Int(1.5)
        Percent += Int(agePercent)
        percentText = String(Percent) + "%"
    }
    
    // Functions for typo menu
    
    func calculateTypoPercent() {
       let typoPercent = numTypos / 2
       Percent += Int(typoPercent)
       percentText = String(Percent) + "%"
    }
    
    func changeTypoMenu() {
        //Changes variables for menu text
        
        menuTypoTitle = "Choose"
        OneToFive = "1-5"
        SixToTen = "6-10"
        Eleven = "11-15"
        TwentyUp = "20+"
    }
    
    func changeTypoTo5() {
        numTypos = 5
        calculateTypoPercent()
    }
    
    func changeTypoTo10() {
        numTypos = 10
        calculateTypoPercent()
    }
    
    func changeTypoTo15() {
        numTypos = 15
        calculateTypoPercent()
    }
    
    func highNumTypos() {
        numTypos = 20
        calculateTypoPercent()
    }
    
    var body: some View {
    
        
        VStack {
            
            // Instances to use later
            
        Text("Scam Inspector")
            .fontWeight(.heavy).font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/).foregroundColor(.green).bold()
       
          
            
            HStack {
            
            VStack {
                
               
                
                // Question
                
                Text(percentText).font(.title2).bold().foregroundColor(.black)
                Text(QuestionText).padding(.top, 90.866).font(.title).foregroundColor(.green).transition(.slide)
               
                // Menus
               
                if stepNum == 1 {
                Menu("Choose") { // Menu for typos
                    Button(SixToTen, action: changeTypoTo10)
                    Button(Eleven, action: changeTypoTo15)
                    Button(TwentyUp, action: highNumTypos)
                }
                    
                } else if stepNum == 3 {
                
                Menu("Choose") { // Menu for age
                    Button(lowAgeVar, action: LowAge)
                    Button(mediumAgeVar, action: mediumAge)
                    Button(highAgeVar, action: highAge)
                }
                } else if stepNum == 4 {
                    Menu("Choose") { // Menu for age
                        Button(lowAgeVar, action: LowAge)
                        Button(mediumAgeVar, action: mediumAge)
                        Button(highAgeVar, action: highAge)
                }
                } else if stepNum == 5 {
                    Menu("Choose") { // Menu for age
                        Button(lowAgeVar, action: LowAge)
                        Button(mediumAgeVar, action: mediumAge)
                        Button(highAgeVar, action: highAge)
                    }
                } else if stepNum == 6 {
                    
                }
                
                TextField("Username", text: userName)
                    .padding(.horizontal)
              

               
                
                                
               
                
                

                Spacer()
                Button(action: {
                    
                    print("Starting process")
                    
                    
                    // If statements to check what stage
                    
                    if stepNum == 0 {
                        stepNum = 1
                        
                        // Change view properties
                        changeTypoMenu()
                        QuestionText = "By estimation, how many typos have they had in the first couple messages?"
                        nextButtonImage = "play"
                        nextButtonText = "Next"
                        percentText = String(Percent) + "%"
                        
                    } else if stepNum == 1 {
                        
                        stepNum = 2
                        
                        removeAllText()
                        
                        QuestionText = "Now it is time to look at their Roblox and Discord profiles! Click NEXT when you are ready to proceed!"
                    
                   
                        
                    } else if stepNum == 2 {
                        stepNum = 3
                        
                        removeAllText()
                        
                        QuestionText = "Look at their Roblox profile! How old is it?"
                        
                        menuAgeTitle = "Choose"
                        
                        lowAgeVar = "6 Months or Less"
                        
                        mediumAgeVar = "1-2 Years"
                        
                        highAgeVar = "3+ Years"
                        
                        
                    } else if stepNum == 3 {
                        stepNum = 4
                        
                        removeAllText()
                        
                        QuestionText = "Look at their Discord profile! How old is it?"
                        
                        menuAgeTitle = "Choose"
                        
                        lowAgeVar = "6 Months or Less"
                        
                        mediumAgeVar = "1-2 Years"
                        
                        highAgeVar = "3+ Years"
                        
                        
                    } else if stepNum == 4 {
                        stepNum = 5
                        
                        removeAllText()
                        
                        QuestionText = "Look at their Developer Forum profile! How old is it?"
                        
                        menuAgeTitle = "Choose"
                        
                        lowAgeVar = "6 Months or Less"
                        
                        mediumAgeVar = "1-2 Years"
                        
                        highAgeVar = "3+ Years"
                        
                        
                    } else if stepNum == 5 {
                        
                        stepNum = 6
                        
                        removeAllText()
                        
                        QuestionText = "What is their Roblox USERname? (Not DISPLAYname)"
        
                    }
                    
                    
                   
                    
                    
                    
                }, label: {
                    Image(systemName: nextButtonImage)
                })
                Text(nextButtonText).foregroundColor(.green)
            }.accentColor(.green)
            
            }
        
        }
        .padding(.top, 5.7)
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ContentView()
            ContentView()
                .previewDisplayName("iPod Touch")
                
        }
            
            
    }
}
}

1 Like

Your preview struct is nested inside your ContentView. Select the entire file and use ⌃I to reindent your code. Correct the incorrect indentation.

Even making that correction, you really need to look into restructuring your code. There is simply no need for separate changeTypoTo5, changeTypoTo10, etc. functions. And all that code in that one button! Whew! Extract your logic to functions and computed properties.

Ideally, you want your Views to be as simple as possible. Use composition to make smaller Views and combine them into a larger View. Don’t try to cram everything into one body property.

1 Like

It’s super complicated to read and understand your code.

Can you pull the logic and methods out of the view structure and put them into a separate view model?

You can probably consolidate many of the functions and pass parameters into them rather than having so many separate functions as well.

Hello again! I haven’t had much time to work on things lately, so I just went to implement the changes you had mentioned, when I ran into a bunch of peculiar errors that were not appearing before. Such as:

Currently, I am breaking most of my if statements that make things run into separate views, but when I delete some of them, all of these errors show up. Do you know what is happening?

Current View Code
//
//  ContentView.swift
//  Scam Inspector
//
//  Created by Hendric Voris on 4/18/21.
//

import SwiftUI

struct ContentView: View {
    
    @State var Percent = 0
    @State var percentText = ""
    @State var nextButtonText = "Start"
    @State var nextButtonImage = "play.fill"
    @State var QuestionText = ""
    @State var QuestionNum = 0
    @State var numTypos = 0
    @State var stepNum = 0
    @State var ageNum = 0
    @State var temporaryTypoPercent = 0.0
    @State var userName = ""
    
    //Generic menu variables
    
    @State var menuTypoTitle = ""
    @State var menuAgeTitle = ""
    
    //Typo variables
    
    @State var OneToFive = ""
    @State var SixToTen = ""
    @State var Eleven = ""
    @State var TwentyUp = ""
    
    // Age variables
    
    @State var highAgeVar = ""
    @State var mediumAgeVar = ""
    @State var lowAgeVar = ""
    
    
    // Functions
    
    func removeAllText() {
        menuTypoTitle = ""
        menuAgeTitle = ""
        OneToFive = ""
        SixToTen = ""
        Eleven = ""
        TwentyUp = ""
    }
    
    // Functions for age menu
    
    func calculateAgePercent() {
        let double = Double(ageNum)
        let agePercent = double * 1.5
        temporaryTypoPercent = agePercent
    }
    
    func LowAge() {
        numTypos = 6
        calculateAgePercent()
    }
    
    func mediumAge() {
        ageNum = Int(1.5)
        let agePercent = ageNum * Int(1.5)
        Percent += Int(agePercent)
        percentText = String(Percent) + "%"
    }
    
    func highAge() {
        ageNum = 1
        let agePercent = ageNum * Int(1.5)
        Percent += Int(agePercent)
        percentText = String(Percent) + "%"
    }
    
    // Functions for typo menu
    
    func calculateTypoPercent() {
       let typoPercent = numTypos / 2
       Percent += Int(typoPercent)
       percentText = String(Percent) + "%"
    }
    
    func changeTypoMenu() {
        //Changes variables for menu text
        
        menuTypoTitle = "Choose"
        OneToFive = "1-5"
        SixToTen = "6-10"
        Eleven = "11-15"
        TwentyUp = "20+"
    }
    
    func changeTypo(number: Int) {
        
        numTypos = number
        
        calculateTypoPercent()
        
    }
    
    
    var body: some View {
    
        
        VStack {
            
            // Instances to use later
            
        Text("Scam Inspector")
            .fontWeight(.heavy).font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/).foregroundColor(.green).bold()
       
          
            
            HStack {
            
            VStack {
                
               
                
                // Question
                
                Text(percentText).font(.title2).bold().foregroundColor(.black)
                Text(QuestionText).padding(.top, 90.866).font(.title).foregroundColor(.green).transition(.slide)
               
                // Menus
               
                if stepNum == 1 {
                Menu("Choose") { // Menu for typos
                    Button(SixToTen, action: changeTypo(10))
                    Button(Eleven, action: changeTypo(15))
                    Button(TwentyUp, action: changeTypo(20))
                }
                    
                } else if stepNum == 3 {
                
                Menu("Choose") { // Menu for age
                    Button(lowAgeVar, action: LowAge)
                    Button(mediumAgeVar, action: mediumAge)
                    Button(highAgeVar, action: highAge)
                }
              

               
                
                                
               
                
                

                Spacer()
                Button(action: {
                    
                    print("Starting process")
                    
                    
                    // If statements to check what stage
                    
                    if stepNum == 0 {
                        stepNum = 1
                        
                        // Change view properties
                        changeTypoMenu()
                        QuestionText = "By estimation, how many typos have they had in the first couple messages?"
                        nextButtonImage = "play"
                        nextButtonText = "Next"
                        percentText = String(Percent) + "%"
                        
                    } else if stepNum == 1 {
                        
                        stepNum = 2
                        
                        removeAllText()
                        
                        QuestionText = "Now it is time to look at their Roblox and Discord profiles! Click NEXT when you are ready to proceed!"
                    
                   
                        
                    } else if stepNum == 2 {
                        stepNum = 3
                        
                        removeAllText()
                        
                        QuestionText = "Look at their Roblox profile! How old is it?"
                        
                        menuAgeTitle = "Choose"
                        
                        lowAgeVar = "6 Months or Less"
                        
                        mediumAgeVar = "1-2 Years"
                        
                        highAgeVar = "3+ Years"
                        
                        
                    } else if stepNum == 3 {
                        stepNum = 4
                        
                        removeAllText()
                        
                        QuestionText = "Look at their Discord profile! How old is it?"
                        
                        menuAgeTitle = "Choose"
                        
                        lowAgeVar = "6 Months or Less"
                        
                        mediumAgeVar = "1-2 Years"
                        
                        highAgeVar = "3+ Years"
                        
                    }
                    
                   
                    
                    
                    
                }, label: {
                    Image(systemName: nextButtonImage)
                })
                Text(nextButtonText).foregroundColor(.green)
            }.accentColor(.green)
            
            }
        
        }
        .padding(.top, 5.7)
}
    
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ContentView()
                .previewDisplayName("iPod Touch")
                
        }
            
            
    }
}
}

Try this:

struct ContentView: View {

    @State var Percent = 0
    @State var percentText = ""
    @State var nextButtonText = "Start"
    @State var nextButtonImage = "play.fill"
    @State var QuestionText = ""
    @State var QuestionNum = 0
    @State var numTypos = 0
    @State var stepNum = 0
    @State var ageNum = 0
    @State var temporaryTypoPercent = 0.0
    @State var userName = ""

    //Generic menu variables

    @State var menuTypoTitle = ""
    @State var menuAgeTitle = ""

    //Typo variables

    @State var OneToFive = ""
    @State var SixToTen = ""
    @State var Eleven = ""
    @State var TwentyUp = ""

    // Age variables

    @State var highAgeVar = ""
    @State var mediumAgeVar = ""
    @State var lowAgeVar = ""


    // Functions

    func removeAllText() {
        menuTypoTitle = ""
        menuAgeTitle = ""
        OneToFive = ""
        SixToTen = ""
        Eleven = ""
        TwentyUp = ""
    }

    // Functions for age menu

    func calculateAgePercent() {
        let double = Double(ageNum)
        let agePercent = double * 1.5
        temporaryTypoPercent = agePercent
    }

    func LowAge() {
        numTypos = 6
        calculateAgePercent()
    }

    func mediumAge() {
        ageNum = Int(1.5)
        let agePercent = ageNum * Int(1.5)
        Percent += Int(agePercent)
        percentText = String(Percent) + "%"
    }

    func highAge() {
        ageNum = 1
        let agePercent = ageNum * Int(1.5)
        Percent += Int(agePercent)
        percentText = String(Percent) + "%"
    }

    // Functions for typo menu

    func calculateTypoPercent() {
        let typoPercent = numTypos / 2
        Percent += Int(typoPercent)
        percentText = String(Percent) + "%"
    }

    func changeTypoMenu() {
        //Changes variables for menu text

        menuTypoTitle = "Choose"
        OneToFive = "1-5"
        SixToTen = "6-10"
        Eleven = "11-15"
        TwentyUp = "20+"
    }

    func changeTypo(number: Int) {

        numTypos = number

        calculateTypoPercent()

    }


    var body: some View {


        VStack {

            // Instances to use later

            Text("Scam Inspector")
                .fontWeight(.heavy).font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/).foregroundColor(.green).bold()



            HStack {

                VStack {



                    // Question

                    Text(percentText).font(.title2).bold().foregroundColor(.black)
                    Text(QuestionText).padding(.top, 90.866).font(.title).foregroundColor(.green).transition(.slide)

                    // Menus

                    if stepNum == 1 {
                        Menu("Choose") { // Menu for typos
                            Button(SixToTen, action: { changeTypo(number: 10) })
                            Button(Eleven, action: { changeTypo(number: 15) })
                            Button(TwentyUp, action: { changeTypo(number: 20) })
                        }

                    } else if stepNum == 3 {

                        Menu("Choose") { // Menu for age
                            Button(lowAgeVar, action: LowAge)
                            Button(mediumAgeVar, action: mediumAge)
                            Button(highAgeVar, action: highAge)
                        }

                    }

                    Spacer()

                    Button(action: {

                        print("Starting process")


                        // If statements to check what stage

                        if stepNum == 0 {
                            stepNum = 1

                            // Change view properties
                            changeTypoMenu()
                            QuestionText = "By estimation, how many typos have they had in the first couple messages?"
                            nextButtonImage = "play"
                            nextButtonText = "Next"
                            percentText = String(Percent) + "%"

                        } else if stepNum == 1 {

                            stepNum = 2

                            removeAllText()

                            QuestionText = "Now it is time to look at their Roblox and Discord profiles! Click NEXT when you are ready to proceed!"



                        } else if stepNum == 2 {
                            stepNum = 3

                            removeAllText()

                            QuestionText = "Look at their Roblox profile! How old is it?"

                            menuAgeTitle = "Choose"

                            lowAgeVar = "6 Months or Less"

                            mediumAgeVar = "1-2 Years"

                            highAgeVar = "3+ Years"


                        } else if stepNum == 3 {
                            stepNum = 4

                            removeAllText()

                            QuestionText = "Look at their Discord profile! How old is it?"

                            menuAgeTitle = "Choose"

                            lowAgeVar = "6 Months or Less"

                            mediumAgeVar = "1-2 Years"

                            highAgeVar = "3+ Years"

                        }





                    }, label: {
                        Image(systemName: nextButtonImage)
                    })
                    Text(nextButtonText).foregroundColor(.green)
                }.accentColor(.green)

            }

        }
        .padding(.top, 5.7)
    }
}
1 Like