When setting up TimerView
and CountdownView
you have CountdownTimer
own updating timeRemaining
with
var body: some View {
Text("\(timeRemaining)") // 5
.font(.system(size: size, design: .rounded))
.padding()
.onChange(of: date) { oldValue, newValue in
timeRemaining -= 1
}
}
Delegating that responsibility to the body of some subview via binding seems messy, you should just do that w/in the context
block of TimelineView.animation
TimelineView(
.animation(
minimumInterval: 1.0,
paused: timeRemaining <= 0)) { context in
CountdownView( // 4
date: context.date,
timeRemaining: $timeRemaining,
size: size)
.onChange(of: context.date) { oldValue, newValue in
timeRemaining -= 1
}
}
As a general suggestion I’m finding the use of onChange, onAppear, etc functionally to be haphazardly implemented, often just attached to whatever view was most recently being discussed w/no regard to performance, data flow, or architecture. I realize to some extent this book is over indexing on using SwiftUI when in many instances you should probably setup your own modes/services outside of the SwiftUI view structs but still, I’m looking to this book to provide optimal patterns for SwiftUI development. For example in Chapter 7, attaching an onAppear()
to a Image view w/in a foreach loop is a bad idea.