4

So I am building a blackjack simulator game and my problem right now is making it more realistic. From when I press the "Hit Me" button I'd like a delay before my next card is uploaded. Similarily when the next player goes I'd also like a delay. So right now I have aplayer view a hand view and a card view. The player and hand are both observables.

    var body: some View {
        HStack {
            VStack(alignment: .trailing, spacing: 0){
                ForEach(0..<self.player.hands.count, id: \.self) {
                    index in ZStack {
                        Spacer()
                        HandView.init(hand: self.player.hands[index])
                    }
                }
                Spacer().frame(height: 45)
                Text(self.player.id).bold().font(Font.system(size: 20))
                Spacer()
            }
            .padding(.all)
            if !player.isRobot{
                VStack{Button(action: {
                    self.player.requestCard()
                }, label: {
                    Text("Hit Me!")
                })
                    Button(action: {
                        self.player.handleInput(turn: turnPosibilities.stay)
                        self.player.objectWillChange.send()
                    }, label: {
                        Text("Stay")
                    })}
                    .offset(x: 10, y: 0)}
        }
    }
    @ObservedObject var hand:Hand
    var bust: some View {
        GeometryReader { geometry in
            Path { path in
                path.move(to: CGPoint.init(x: geometry.frame(in: .local).midX, y: CGFloat(geometry.frame(in: .local).midY)))
                path.addLine(to: CGPoint.init(x: geometry.frame(in: .local).minX, y: geometry.frame(in: .local).minY))
                path.addLine(to: CGPoint.init(x: geometry.frame(in: .local).minX, y: geometry.frame(in: .local).maxY))
                path.addLine(to: CGPoint.init(x: geometry.frame(in: .local).maxX, y: geometry.frame(in: .local).maxY))
                path.addLine(to: CGPoint.init(x: geometry.frame(in: .local).maxX, y: geometry.frame(in: .local).minY))
            }
            .fill(Color.red)
        }
    }

    var body: some View {
        ZStack
            {ForEach(0..<self.hand.cards.count, id: \.self){
                card in
                VStack(alignment: .leading, spacing: 2) {PlayingCardView(rank: self.hand.cards[card].rankRaw, suit: self.hand.cards[card].suit, isFaceUp: self.hand.cards[card].isFaceUp ).rotationEffect(Angle.init(degrees: Double(multiply(index: card, offset: 10))))
                    .offset(x: multiply(index: card, offset: 15), y: multiply(index: card, offset: 40))

                }
                }

        }
    }
}
        ZStack{
            if isFaceUp {
                Rectangle().frame(width: 130, height:182).foregroundColor(Color.init(#colorLiteral(red: 0.9999127984, green: 1, blue: 0.9998814464, alpha: 1))).cornerRadius(25).overlay(Image(self.suit.rawValue).resizable().aspectRatio(contentMode: .fit).padding(.all))
                Text(String(self.rank)).font(.custom("Poppins-SemiBoldItalic", size: 40)).offset(x: 29, y: -70)
                Text(String(self.rank)).font(.custom("Poppins-SemiBoldItalic", size: 40)).offset(x: 29, y: -70).rotationEffect(Angle.init(degrees: 180))
            }
            else {
                Rectangle().frame(width: 130, height:182).foregroundColor(Color.init(UIColor(red: 0.58, green: 0.65, blue: 0.65, alpha: 1.00)
                )).cornerRadius(25)
            }
        }.clipShape(RoundedRectangle(cornerRadius: 25)).overlay(RoundedRectangle(cornerRadius: 25).stroke(Color.black, lineWidth: 2))
    }
Rohan Garg
  • 45
  • 1
  • 5

2 Answers2

6

Here is possible approach

VStack{Button(action: {
    DispatchQueue.main.asyncAfter(deadline: .now() + 1) { // 1 sec delay
         self.player.requestCard()
    }
}, label: {
    Text("Hit Me!")
})
Asperi
  • 228,894
  • 20
  • 464
  • 690
2

This can be achieved in SwiftUI by defining a @State variable / flag and showing new view based on that. In the below code snippet showSecondView determines when to show the next view.

struct ContentView: View {
@State var showSecondView = false
var body: some View {
    Group {
        Text("Hello, World!")
            .font(.largeTitle)
            .foregroundColor(.primary)
        if showSecondView {
            Text("SecondView")
                .font(.title)
                .foregroundColor(.secondary)
        }
    }
    .onAppear() {
        Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { (_) in
            withAnimation {
                self.showSecondView = true
            }
        }
    }
}
Pankaj Kulkarni
  • 553
  • 4
  • 12
  • This works only once, after 2 seconds you will have that view forever, what if i want to reset the seconds? My view appears continuously and i want that every time it appears it waits 2 seconds and then show me the view – Fabez Aug 12 '22 at 17:01
  • @Fabez readily the second view should have a binding variable which should reset the showSecondView when it is dismissed. Or you need another timer (like in onAppear()) to reset the boolean showSecondView to false. – Pankaj Kulkarni Aug 14 '22 at 06:25