微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在CADisplayLink动画期间更新视图

如何解决如何在CADisplayLink动画期间更新视图

我正在尝试使用CAdisplayLink实现一个简单的动画。黑色正方形应该在屏幕上缓慢移动。

但是正方形看起来是静止的,因为body递增testX和testY时Squares的{​​{1}}不会得到更新。

据我所知(我是Swift的新手),我正确地使用了step()范例,所以我不明白为什么视图不会刷新。

如何获得@Observedobject的{​​{1}}和动画一起更新?

下面是我的代码,谢谢您的帮助!

Squares

解决方法

据我所知,您需要的是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
        }
    }
}
,

这是因为您的displaylink是在堆栈上创建的,因此在退出函数后立即被销毁。您需要将其设置为属性。

此处是经过修改的经过测试的代码。在Xcode 12 / iOS 14上进行了测试。

demo

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,height: 50))
        }
        .fill(Color.black)
        .onAppear {
            animation.createDisplayLink()
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。