Implement round timer functionality and add a deck reset button

This commit is contained in:
CypherPoet 2020-01-20 15:12:24 -06:00
parent 65b99570dc
commit b5cd26488c
3 changed files with 68 additions and 31 deletions

View File

@ -40,9 +40,10 @@ extension CardDeckContainerView {
@Published var cards: [Card] = []
@Published var timeRemaining: TimeInterval
// MARK: - Init
init(
roundDuration: TimeInterval = 10.0
roundDuration: TimeInterval = 100.0
) {
self.roundDuration = roundDuration
self.timeRemaining = roundDuration
@ -80,10 +81,11 @@ extension CardDeckContainerView.ViewModel {
// MARK: - Computeds
extension CardDeckContainerView.ViewModel {
var timeRemainingText: String {
NumberFormatters.cardCountdown.string(for: timeRemaining) ?? ""
}
var isDeckEmpty: Bool { cards.isEmpty }
}
@ -95,6 +97,18 @@ extension CardDeckContainerView.ViewModel {
try? fetchedResultsController.performFetch()
cards = extractResults(from: fetchedResultsController)
}
func resetDeck() {
fetchCards()
self.timeRemaining = roundDuration
self.isTimerActive = true
}
func pauseRound() {
isTimerActive = false
}
}
@ -116,7 +130,7 @@ private extension CardDeckContainerView.ViewModel {
CurrentApp.notificationCenter
.publisher(for: UIApplication.willEnterForegroundNotification)
.map { _ in true }
.map { _ in self.isDeckEmpty == false }
.assign(to: \.isTimerActive, on: self)
.store(in: &subscriptions)
}

View File

@ -11,8 +11,6 @@ import CypherPoetSwiftUIKit
struct CardDeckContainerView {
@Environment(\.accessibilityDifferentiateWithoutColor) var differentiateWithoutColor
@ObservedObject var viewModel: ViewModel = .init()
}
@ -23,8 +21,8 @@ extension CardDeckContainerView: View {
var body: some View {
GeometryReader { geometry in
ZStack {
VStack {
Text("Time Remaining: \(self.viewModel.timeRemaining)")
VStack(spacing: 22) {
Text("Time Remaining: \(self.viewModel.timeRemainingText)")
.font(.largeTitle)
.foregroundColor(Color.yellow)
.padding(.horizontal)
@ -39,19 +37,22 @@ extension CardDeckContainerView: View {
onRemove: { (card, index) in self.cardRemoved(at: index) }
)
.allowsHitTesting(self.viewModel.timeRemaining > 0)
.padding()
}
if self.differentiateWithoutColor {
if self.viewModel.isDeckEmpty {
VStack {
Spacer()
self.swipeDirectionIndicators
HStack {
Spacer()
self.resetButton
}
}
}
}
}
.padding()
.padding()
.background(Color("CardDeckBackground"))
.edgesIgnoringSafeArea(.all)
}
@ -66,24 +67,12 @@ extension CardDeckContainerView {
// MARK: - View Variables
extension CardDeckContainerView {
private var swipeDirectionIndicators: some View {
HStack {
Image(systemName: "xmark.circle")
.padding()
.background(Color.black.opacity(0.7))
.clipShape(Circle())
Spacer()
Image(systemName: "checkmark.circle")
.padding()
.background(Color.black.opacity(0.7))
.clipShape(Circle())
}
.foregroundColor(.white)
.font(.largeTitle)
private var resetButton: some View {
Button("Start Again", action: viewModel.resetDeck)
.padding()
.background(Color.white)
.foregroundColor(.black)
.clipShape(Capsule())
}
}
@ -94,6 +83,10 @@ extension CardDeckContainerView {
private extension CardDeckContainerView {
func cardRemoved(at index: Int) {
viewModel.cards.remove(at: index)
if viewModel.isDeckEmpty {
viewModel.pauseRound()
}
}
}
@ -105,7 +98,6 @@ struct CardDeckContainerView_Previews: PreviewProvider {
static var previews: some View {
CardDeckContainerView()
.environment(\.managedObjectContext, CurrentApp.coreDataManager.mainContext)
// .environment(\.accessibilityDifferentiateWithoutColor, .constant(true))
.previewLayout(PreviewLayout.iPhone11Landscape)
// .previewLayout(PreviewLayout.iPhone11Landscape)
}
}

View File

@ -10,6 +10,8 @@ import SwiftUI
struct CardDeckView {
@Environment(\.accessibilityDifferentiateWithoutColor) var differentiateWithoutColor
var width: CGFloat
var height: CGFloat
@ -33,7 +35,36 @@ extension CardDeckView: View {
)
.stacked(at: index + 1, outOf: deckSize, offsetMultiple: CGFloat(30 / deckSize))
}
if self.differentiateWithoutColor {
VStack {
Spacer()
self.swipeDirectionIndicators
}
}
}
.frame(width: width, height: height)
}
private var swipeDirectionIndicators: some View {
HStack {
Image(systemName: "xmark.circle")
.padding()
.background(Color.black.opacity(0.7))
.clipShape(Circle())
Spacer()
Image(systemName: "checkmark.circle")
.padding()
.background(Color.black.opacity(0.7))
.clipShape(Circle())
}
.foregroundColor(.white)
.font(.largeTitle)
}
}