[英]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.