TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

Project 17, part 4 - Ending the app with allowsHitTesting() - Issue the cards didn't appeared enough

Forums > 100 Days of SwiftUI

Hi everyone,

I am on day 89 (Project 17, part 4 - Ending the app with allowsHitTesting()). When testing on simulator, after removing all cards:

  • If I immediately pressed the button "Start Again", then only few cards appeared (may be 0, 1, 2, or 3 cards ...).
  • But if I waited for some more seconds, then pressed the button "Start Again", it could show enough cards (10 ones as example).

Here is the code of ContentView.swift:

//
//  ContentView.swift
//  Flashzilla
//
//  Created by TIEN on 23/02/2024.
//

import SwiftUI

extension View{
    func stacked(at position: Int, in total: Int) -> some View{
        let offset = Double(total - position)
        return self.offset( y: offset * 10)
    }
}

struct ContentView: View {
    @Environment(\.accessibilityDifferentiateWithoutColor) var accessibilityDifferentiateWithoutColor
    @Environment(\.scenePhase) var scenePhase
    @State private var cards = Array<Card>(repeating: .example, count: 10)
    @State private var timeRemaining = 100
    @State private var isActive = true

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

    var body: some View {
        ZStack{
            Image(.background)
                .resizable()
                .ignoresSafeArea()
            VStack{
                Text("Time: \(timeRemaining)")
                    .font(.largeTitle)
                    .foregroundStyle(.white)
                    .padding(.horizontal, 20)
                    .padding(.vertical, 5)
                    .background(.black.opacity(0.75))
                    .clipShape(.capsule)
                ZStack{

                        ForEach(0..<cards.count, id:\.self){ index in
                            CardView(card: cards[index]){
                                withAnimation{
                                    removeCard(at: index)
                                }

                            }
                            .stacked(at: index, in: cards.count)
                            .allowsHitTesting(index == cards.count - 1)
                        }
                }
                .allowsHitTesting(timeRemaining > 0)
                //For testing
                Text("Card remaining: \(cards.count)")
                if cards.isEmpty {
                    Button("Start Again", action: resetCards)
                        .padding()
                        .background(.white)
                        .foregroundStyle(.black)
                        .clipShape(.capsule)
                        .padding()
                }
            }
            if accessibilityDifferentiateWithoutColor {
                VStack{
                    Spacer()
                    HStack{
                        Image(systemName: "xmark.circle")
                            .padding()
                            .background(.black.opacity(0.7))
                            .clipShape(.circle)
                        Spacer()
                        Image(systemName: "checkmark.circle")
                            .padding()
                            .background(.black.opacity(0.7))
                            .clipShape(.circle)
                    }
                    .foregroundStyle(.white)
                    .font(.largeTitle)
                    .padding()
                }
            }

        }
        .onReceive(timer){time in
            guard isActive else {return}
            if timeRemaining > 0 {
                timeRemaining -= 1
            }
        }
        .onChange(of: scenePhase) { oldPhase, newPhase in
            if newPhase == .active {
                if cards.isEmpty == false{
                    isActive = true
                }
            }else {
                isActive = false
            }
        }
    }
    func removeCard(at index: Int){
        guard index >= 0 else {return}
        cards.remove(at: index)
        if cards.isEmpty {
            isActive = false
        }
    }
    func resetCards(){
        cards.removeAll()
        cards = Array<Card>(repeating: .example2, count: 10)
        timeRemaining = 100
        isActive = true
    }
}

#Preview {
    ContentView()
}

Please help me to solve the problem.

Thank you!

   

I don't think my solution is related to your issue but I noticed in your resetCards() method, you're reinitialising cards the array with .example2 instead of .example when you first loaded ContentView.

  func resetCards(){
        cards.removeAll()
        cards = Array<Card>(repeating: .example2, count: 10)
        timeRemaining = 100
        isActive = true
    }

Could you try changing it to .example instead?

   

Hacking with Swift is sponsored by Blaze.

SPONSORED Still waiting on your CI build? Speed it up ~3x with Blaze - change one line, pay less, keep your existing GitHub workflows. First 25 HWS readers to use code HACKING at checkout get 50% off the first year. Try it now for free!

Reserve your spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.