Post

Replies

Boosts

Views

Activity

Escaping closure captures mutating 'self' parameter Error
Creating a simple card game (Set) and I have a function in the model that deals X cards onto the deck. Currently, when I click the deal card button they all show up at once so I added the timer so that they would appear one after another. This gives the error "Escaping closure captures mutating 'self' parameter" Any ideas on what I can fix? mutating func deal(_ numberOfCards: Int) { for i in 0..<numberOfCards { Timer.scheduledTimer(withTimeInterval: 0.3 * Double(i), repeats: false) { _ in if deck.count > 0 { dealtCards.append(deck.removeFirst()) } } } }
5
0
15k
Jun ’20
Locate position of other view SwiftUI for animation.
I am building a card game (Set) and when dealing the cards I am currently using withAnimation{} and .transition(.move(edge: .bottom) to have the cards animate from the bottom edge of the screen when the user taps the deal button. I want to make it so that the cards 'fly out' of the button and was wondering how I find the location of the button. Once I find the position of the button I intend to use .offset to have them 'fly' out. Is there a better way? I know it is possible using geometry reader, but I have not found out how to do so. Here is my current code: struct SetGameView: View { &#9;&#9; &#9;&#9;@ObservedObject var viewModel: SetViewModel = SetViewModel() &#9;&#9;var location: (CGFloat, CGFloat) = (0.0, 0.0)&#9; &#9;&#9;var body: some View { &#9;&#9;&#9;&#9;VStack { &#9;&#9;&#9;&#9;&#9;&#9;HStack { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Label("Score: \(viewModel.score)", systemImage: "face.dashed").font(.title).padding(.leading) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Spacer() &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;Grid(viewModel.dealtCards) { card in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;CardView(card: card) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.transition(.asymmetric(insertion: .move(edge: .bottom), removal: .move(edge: .leading))) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.padding() &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.onTapGesture { withAnimation { viewModel.choose(card) } } &#9;&#9;&#9;&#9;&#9;&#9;} .onAppear { withAnimation(.easeInOut) { deal(12) } } &#9;&#9;&#9;&#9;&#9;&#9;Divider() &#9;&#9;&#9;&#9;&#9;&#9;HStack { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;CreateNewGameButton(viewModel: viewModel) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;DealNewCardbutton(viewModel: viewModel, deal: deal) &#9;&#9;&#9;&#9;&#9;&#9;}.padding(.horizontal).frame(maxHeight: 50) &#9;&#9;&#9;&#9;} &#9;&#9;} &#9;&#9; &#9;&#9;struct DealNewCardbutton: View { &#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;var viewModel: SetViewModel &#9;&#9;&#9;&#9;let deal: (Int) -> Void &#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;init(viewModel: SetViewModel, deal: @escaping (Int) -> Void) { &#9;&#9;&#9;&#9;&#9;&#9;self.viewModel = viewModel &#9;&#9;&#9;&#9;&#9;&#9;self.deal = deal &#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;var body: some View { &#9;&#9;&#9;&#9;&#9;&#9;GeometryReader { geo in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Button(action: { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;deal(3) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;}){ &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;ZStack { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;RoundedRectangle(cornerRadius: 10.0).foregroundColor(.blue) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text("Deal Three Cards").foregroundColor(.white) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;}.onAppear { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;print(geo.frame(in: .global).midX, geo.frame(in: .global).midY) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;} &#9;&#9;} [Here](https://www.icloud.com/iclouddrive/0rJS9eRGgicAcpumvfJiTjd7Q#RPReplay_Final1593385736 https://www.icloud.com/iclouddrive/0rJS9eRGgicAcpumvfJiTjd7Q#RPReplay_Final1593385736) is a video depicting how the animation currently works. I want the cards to all 'fly out' from the deal button.
0
0
402
Jun ’20
Locate position of view in SwiftUI
I am building a card game (Set) and when dealing the cards I am currently using withAnimation{} and .transition(.move(edge: .bottom) to have the cards animate from the bottom edge of the screen when the user taps the deal button. I want to make it so that the cards 'fly out' of the button and was wondering how I find the location of the button. Once I find the position of the button I intend to use .offset to have them 'fly' out. Is there a better way? I know it is possible using geometry reader, but I have not found out how to do so. Here is my current code &#9;&#9;struct SetGameView: View { &#9;&#9; &#9;&#9; @ObservedObject var viewModel: SetViewModel = SetViewModel() &#9;&#9; var location: (CGFloat, CGFloat) = (0.0, 0.0)&#9; &#9;&#9; var body: some View { &#9;&#9; VStack { &#9;&#9; HStack { &#9;&#9; Label("Score: \(viewModel.score)", systemImage: "face.dashed").font(.title).padding(.leading) &#9;&#9; Spacer() &#9;&#9; } &#9;&#9; Grid(viewModel.dealtCards) { card in &#9;&#9; CardView(card: card) &#9;&#9; .transition(.asymmetric(insertion: .move(edge: .bottom), removal: .move(edge: .leading))) &#9;&#9; .padding() &#9;&#9; .onTapGesture { withAnimation { viewModel.choose(card) } } &#9;&#9; } .onAppear { withAnimation(.easeInOut) { deal(12) } } &#9;&#9; Divider() &#9;&#9; HStack { &#9;&#9; CreateNewGameButton(viewModel: viewModel) &#9;&#9; DealNewCardbutton(viewModel: viewModel, deal: deal) &#9;&#9; }.padding(.horizontal).frame(maxHeight: 50) &#9;&#9; } &#9;&#9; } &#9;&#9; &#9;&#9; struct DealNewCardbutton: View { &#9;&#9; &#9;&#9; var viewModel: SetViewModel &#9;&#9; let deal: (Int) -> Void &#9;&#9; &#9;&#9; init(viewModel: SetViewModel, deal: @escaping (Int) -> Void) { &#9;&#9; self.viewModel = viewModel &#9;&#9; self.deal = deal &#9;&#9; } &#9;&#9; &#9;&#9; var body: some View { &#9;&#9; GeometryReader { geo in &#9;&#9; Button(action: { &#9;&#9; deal(3) &#9;&#9; }){ &#9;&#9; ZStack { &#9;&#9; RoundedRectangle(cornerRadius: 10.0).foregroundColor(.blue) &#9;&#9; Text("Deal Three Cards").foregroundColor(.white) &#9;&#9; } &#9;&#9; }.onAppear { &#9;&#9; print(geo.frame(in: .global).midX, geo.frame(in: .global).midY) &#9;&#9; } &#9;&#9; } &#9;&#9; } &#9;&#9; } Heres - https://www.icloud.com/iclouddrive/0rJS9eRGgicAcpumvfJiTjd7Q#RPReplay_Final1593385736 a video of how it currently works. I want the cards to all 'fly out' from the deal button.
1
0
3.2k
Jun ’20
Delay in For loop
I am creating a simple card game (Set) in SwiftUI. I have a button that will deal X new cards when tapped. Currently, it makes all cards show up at once. I was wondering how I could make them come out one at a time. Deal works by appending a new card to a Deck array in the model. ContentView displays each card in the grid. func deal(_ numberOfCards: Int) { withAnimation(Animation.easeInOut(duration: 1)) { viewModel.deal() } for _ in 1..<numberOfCards { DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) { withAnimation(.easeInOut) { viewModel.deal() } } } }
1
1
2.3k
Jun ’20