[英]How to update a view during a CADisplayLink animation
我正在嘗試使用CADisplayLink
實現一個簡單的動畫。 黑色方塊應該在屏幕上緩慢移動。
但是正方形看起來是靜止的,因為當step()
增加 testX 和 testY 時Squares
的body
沒有得到更新。
據我所知(我是 Swift 新手),我正確使用了@ObservedObject
范例,所以我不明白為什么視圖不會刷新。
如何讓Squares
的body
與動畫一起更新?
我的代碼如下,感謝您的幫助!
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()
}
}
這是因為你displaylink
是在棧創建的,就這么被毀了從函數退出之后。 你需要讓它成為財產。
這是修改后的測試代碼。 使用 Xcode 12 / iOS 14 測試。
class MyAnimations: NSObject, ObservableObject {
@Published var testX: Double = 0
@Published var testY: Double = 0
private var displaylink: CADisplayLink! // << here !!
func createDisplayLink() {
if nil == displaylink {
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)
.onAppear {
animation.createDisplayLink()
}
}
}
從我看來,您只需要一個ObservableObject
的共享實例
class MyAnimations: NSObject, ObservableObject {
@Published var testX: Double = 0
@Published var testY: Double = 0
static let sharedInstance: MyAnimations = MyAnimations()//Singleton Pattern
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.sharedInstance//Singleton Pattern
@EnvironmentObject var animation: MyAnimations
var body: some View {
VStack{
Button("Move", action: {
animation.createDisplayLink()
})
Path { path in
path.addRect(CGRect(x: self.animation.testX, y: self.animation.testY, width: 50, height: 50))
}
.fill(Color.black)
}
}
}
struct SomeOtherView: View {
@ObservedObject var animation = MyAnimations()
//@ObservedObject var animation = MyAnimations.sharedInstance//Singleton Pattern
var body: some View {
VStack{
Button("Trigger to Create", action: {
animation.createDisplayLink()
})//Sample Trigger
Squares()
.environmentObject(animation)//Omit if using Singleton
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.