When I study the SwiftUI Apprentice book of Kodeco, I come across the below code snippet.
struct CountdownView: View {
let date: Date
@Binding var timeRemaining: Int
let size: Double
var body: some View {
Text("\(timeRemaining)") // 5
.font(.system(size: size, design: .rounded))
.padding()
.onChange(of: date) { _ in // 6
timeRemaining -= 1
}
}
}
struct TimerView: View {
@State private var timeRemaining: Int = 3 // 1
@Binding var timerDone: Bool // 2
let size: Double
var body: some View {
TimelineView( // 3
.animation(
minimumInterval: 1.0,
paused: timeRemaining <= 0)) { context in
CountdownView( // 4
date: context.date,
timeRemaining: $timeRemaining,
size: size)
}
.onChange(of: timeRemaining) { _ in
if timeRemaining < 1 {
timerDone = true // 7
}
}
}
}
struct TimerView_Previews: PreviewProvider {
static var previews: some View {
TimerView(timerDone: .constant(false), size: 90)
}
}
When I examine the code snippet, I firstly expected to be recreated CountdownView. But there would be no change on date property in that case. Then, I added onAppear modifier to CountdownView to detect the recreating of the view. As a result, it is created only once. I come up with a question to help me to understand the view rending mechanism of SwiftUI, on which I still work that although date property is a constant and does not use @Binding how is it possible to observe the change of a data that is declared as a constant in SwiftUI?




