I'm trying to implement a simple animation using CADisplayLink
. A black square should move slowly across the screen.
But the square appears stationary because the body
of Squares
doesn't get updated when step()
increments testX and testY.
From what I can gather (I'm new to Swift), I'm using the @ObservedObject
paradigm correctly, so I don't understand why the view won't refresh.
How do I get Squares
's body
to update along with the animation?
My code is below, thanks for your help!
class MyAnimations: NSObject, ObservableObject {
@Published var testX: Double = 0
@Published var testY: Double = 0
func createDisplayLink() {
let displaylink = CADisplayLink(target: self, selector: #selector(step))
displaylink.add(to: .current, forMode: RunLoop.Mode.default)
}
@objc func step(link: CADisplayLink) {
testX += 0.5
testY += 0.5
}
}
struct Squares: View {
@ObservedObject var animation = MyAnimations()
var body: some View {
Path { path in
path.addRect(CGRect(x: self.animation.testX, y: self.animation.testY, width: 50, height: 50))
}
.fill(Color.black)
}
}
struct SomeOtherView: View {
var body: some View {
Squares()
}
}
Update: retested with Xcode 13.4 / iOS 15.5 - works as-is
This is because your
displaylink
is created on stack, so destroyed right after quit from function. You need to make it property.Here is modified tested code. Tested with Xcode 12 / iOS 14.