SwiftUI — Colour Game

lyvennitha sasikumar
3 min readOct 11, 2022

--

Hey guys! I want to share some interesting thing along with some concept in SwiftUI. Here am gonna create a color game which adds score when user pick odd colours out. And user loses 50 from whole score when chooses wrong colour. Here are some pictures on that.

Now am gonna explain how to create that color box. From that we can learn about @ViewBuilder attribute.

You typically use ViewBuilder as a parameter attribute for child view-producing closure parameters, allowing those closures to provide multiple child views.

From the above, we can understand that @ViewBuilder attribute helps to create multiple child view by providing closure. Now create a color box using this attribute.

@ViewBuilder
func ColorView(color: Color) -> some View {
(color )
.cornerRadius(15)
.frame(minHeight: 40)
}

Here i set corner radius and minHeight as static values and make colour as parameter.

Now before going to create stacks of color boxes. Gonna have some variable and constant declarations. And make these as global variable.

let colors: [Color] = [.red, .green, .blue, .yellow, .purple, .cyan, .orange, .gray, .black]let numbers = [0, 1, 2, 3, 4]let opaity = [0.7, 0.8, 0.85, 0.9, 0.75]

Create @State variables and pick random colour and random column and row from a grid.

@State var color = colors.randomElement() ?? .gray@State var randomRow = numbers.randomElement()@State var randomCol = numbers.randomElement()

Now create 5x5 grid of colour boxes and on tapping each box colour, have to change rando colours again and row and column. We can add in tapGesture closures.

VStack{VStack{ForEach(numbers, id: \.self) { row inHStack {ForEach(numbers, id: \.self) { col inColorView(color: col == randomRow && row == randomCol ? color.opacity(opacityValue ?? 0.8):color).frame(width: 50, height: 50).cornerRadius(15).onTapGesture {withAnimation {if col != randomRow || row != randomCol{showWrong.toggle()DispatchQueue.main.asyncAfter(deadline: .now()+1, execute: {showWrong.toggle()})}}if timeRemaining > 0{score = col == randomRow && row == randomCol ? score+100 : score-50 < 0 ? 0: score-50color = colors.randomElement() ?? .grayrandomRow = numbers.randomElement()randomCol = numbers.randomElement()opacityValue = opaity.randomElement()}}}}}}}.frame(width: UIScreen.main.bounds.size.width*0.9, height: UIScreen.main.bounds.size.height*0.4).background(Color.white).cornerRadius(15).shadow(radius: 10)

randomElement() — Call randomElement() to select a random element from an array or another collection.

Now we can set timer to give soul to this colour game which makes it as a challenging one. In SwiftUI, we have to create a publisher which notifies the timer changes. Create a Timer with publisher.

let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

Timer.publish — A publisher that repeatedly emits the current date on the given interval.

autoconnect() — Automates the process of connecting or disconnecting from this connectable publisher.

Now we’ve gonna change Text value of timer according to the declared Timer .

Text("Time Remaining: \(timeRemaining)").onReceive(timer) { _ inif timeRemaining > 0 {timeRemaining -= 1}}

.onReceive — Adds an action to perform when this view detects data emitted by the given publisher.

Now Basic setup is ready. And score is added for odd picks and 50 will reduce for wrong picks.Here is a tap Gesture action of each box.

.onTapGesture {withAnimation {if col != randomRow || row != randomCol{showWrong.toggle()DispatchQueue.main.asyncAfter(deadline: .now()+1, execute: {showWrong.toggle()})}}if timeRemaining > 0{score = col == randomRow && row == randomCol ? score+100 : score-50 < 0 ? 0: score-50color = colors.randomElement() ?? .grayrandomRow = numbers.randomElement()randomCol = numbers.randomElement()opacityValue = opaity.randomElement()}}

Here we’ve learned some new concepts in swiftUI and here is the repo link — https://github.com/LyvennithaQgen/Colour-Gmae. Follow me for more updates.

Here are some OutPut ScreenShots.

HAPPY CODING!❄️

--

--