Trying to Create an Auto Clicker (SwiftUi)

When the button is pressed it should add 1 repetitively to my variable(counter) which is in a string. The counter variable is also set with the @State so I know it’s not that.

Button(“Auto Click + 1”) {
// counter is the points
if counter < 100 {
return
}
repeat {
counter += 1

            }while counter > 1

}

When trying to do this nothing happens? Sorry if this is very vague, I’ve never made a post asking for help.
Thank you.

Hi Liam,

Welcome to the Code Crew community.

There is no way to make a Button tap itself which appears to be what you are suggesting. What I mean is that the code:

if counter < 100 {
    return
}

will result in nothing happening at all because counter will be 0 to begin with which is less than 100.

The following code:

repeat {
    counter += 1
} while counter > 1

will never be executed.

If you replace all the code in your Button closure with just this:

repeat {
    counter += 1
} while counter < 100

then counter will be incremented from 0 to 100 in less than the blink of an eye.

Paste this code in your App

struct ContentView: View {
    @State private var counter = 0

    var body: some View {
        VStack(spacing: 30) {
            Text("\(counter)")

            Button("Increment counter") {

                repeat {
                    counter += 1
                } while counter < 100
            }

            Button("Clear Counter") {
                counter = 0
            }
        }
    }
}

What is your intention overall? Do you want to have a value increment by 1 every second or half second to simulate someone repeatedly tapping the Button or do you have something else in mind?

You might want to consider taking the SwiftUI introductory course that Chris Ching has available. To see all the courses he has available then take a look at this link: learn.codewithchris.com

Hi Chris, let me start by just saying thank you so much for such a thoughtful reply. I have the CWC+ and am about 36% through the Foundation course with SwiftUI. I just thought it would be fun to test my knowledge. I was doing this by creating a Cookie Clicker type app where you tap a monkey and get banana peels. I was trying to make it increment +1 every second, but now I see how that line of code would not work for that. I am at a total loss of how I would perform this, would you need to import sometime of time kit like in python?
This little project is nothing serious, just a way to apply my knowledge as time goes on.
Any help would be appreciated tho!
Thank you, Liam :slight_smile:

Here is the code I have so far, I know their is a much better way to do the opacity stuff, I just couldn’t think of one lol. Also the “monkey” and “peel” are exactly what you think they are.


struct ContentView: View {
@State var counter = 0
@State var clickPower = 1
@State var opacity:Double = 1
@State var opacity1:Double = 0
@State var opacity2:Double = 0
@State var opacity3:Double = 0
@State var opacity4:Double = 1
var body: some View {
VStack {
HStack{
Spacer()
Image(“bannana”).resizable()
Spacer()
}
Text(“You have: (counter) Peels”)
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color.white)
.padding(.all)
.background(/@START_MENU_TOKEN@//@PLACEHOLDER=View@/Color.black/@END_MENU_TOKEN@/)
.cornerRadius(/@START_MENU_TOKEN@/50.0/@END_MENU_TOKEN@/)
Button(action: {
counter += clickPower

        }, label: {
            Image("monkey")
        })
        Button("Click x2 (100 Peels)") {
            if counter < 100 {
                return
            }
            clickPower *= 2
            counter -= 100
            opacity = 0
            opacity1 = 1
            
        }.opacity(opacity).foregroundColor(.yellow).font(.title)
        
        Button("Click x4 (500 Peels)") {
            if counter < 500 {
                return
            }
            clickPower *= 4
            counter -= 500
            opacity1 = 0
            opacity2 = 1
        }.opacity(opacity1).foregroundColor(.yellow).font(.title)
        
        Button("Click x6 (1000 Peels)") {
            if counter < 1000 {
                return
            }
            clickPower *= 6
            counter -= 1000
            opacity2 = 0
            opacity3 = 1
        }.opacity(opacity2).foregroundColor(.yellow).font(.title)
        
        Button("Click x10 (10,000 Peels)") {
            if counter < 10000 {
                return
            }
            clickPower *= 2
            counter -= 10000
            opacity3 = 0
            opacity4 = 1
            
        }.opacity(opacity3).foregroundColor(.yellow).font(.title)
        
        Button("Auto Click + 1/S (1 Point") {
    
            repeat {
                    counter += 1
                        } while counter < 100
            
            
        }.opacity(opacity4).foregroundColor(.yellow).font(.title)
    }

}

}

Hi Liam,

Yeah I don’t quite get what the game intention is and what you are trying to do with each Button but that doesn’t matter for the moment.

There are timers that you can use where you can start and stop them with the appropriate code.

I have modified your code to include a timer. The lower button toggles a Boolean so that the value is automatically incrementing until you tap the button to stop it. If you tap the button again it resumes incrementing the counter. The increment is done in the .onReceive() modifier attached to the VStack.

As an aside, I wasn’t sure what you were using as a banana and a monkey image but I grabbed an icon of each and placed them in the assets folder of the version I have here just for the exercise. I changed the Image() modifiers in each case so that the icons appeared sensible on my screen as per the attached screenshot.

Modified code follows:

struct ContentView: View {
    @State var counter = 0
    @State var clickPower = 1
    @State var opacity:Double = 1
    @State var opacity1:Double = 0
    @State var opacity2:Double = 0
    @State var opacity3:Double = 0
    @State var opacity4:Double = 1

    @State var timerOn = false
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    
    var body: some View {
        VStack {
            Image("bannana")
                .resizable()
                .scaledToFit()
                .frame(width: 200)

            Text("You have: \(counter) Peels")
                .font(.title)
                .fontWeight(.bold)
                .foregroundColor(Color.white)
                .padding(.all)
                .background(Color.black)
                .cornerRadius(50)

            Button(action: {
                counter += clickPower

            }, label: {
                Image("monkey")
                    .resizable()
                    .scaledToFit()
                    .frame(width: 200)
            })

            Button("Click x2 (100 Peels)") {
                if counter < 100 {
                    return
                }
                clickPower *= 2
                counter -= 100
                opacity = 0
                opacity1 = 1

            }.opacity(opacity).foregroundColor(.yellow).font(.title)

            Button("Click x4 (500 Peels)") {
                if counter < 500 {
                    return
                }
                clickPower *= 4
                counter -= 500
                opacity1 = 0
                opacity2 = 1
            }.opacity(opacity1).foregroundColor(.yellow).font(.title)

            Button("Click x6 (1000 Peels)") {
                if counter < 1000 {
                    return
                }
                clickPower *= 6
                counter -= 1000
                opacity2 = 0
                opacity3 = 1
            }.opacity(opacity2).foregroundColor(.yellow).font(.title)

            Button("Click x10 (10,000 Peels)") {
                if counter < 10000 {
                    return
                }
                clickPower *= 2
                counter -= 10000
                opacity3 = 0
                opacity4 = 1

            }.opacity(opacity3).foregroundColor(.yellow).font(.title)

            Button("Auto Click + 1/S (1 Point)") {
                timerOn.toggle()
            }.opacity(opacity4).foregroundColor(.yellow).font(.title)
        }
        .onReceive(timer) { _ in
            if timerOn {
                counter += 1
            }
        }

    }
}

Thank you very very much, this was extremely helpful and I will 1000% be using this in the future.

If I am being completely honest there is not really much of a point to this besides just testing out new skills I am learning in the course. The buttons are supposed to increase the “power” of your click, x2, x4 etc… But now that I understand how to finally do this I can finally sleep in peace.
Thank you again,
Liam