【问题标题】:How to update a view during a CADisplayLink animation如何在 CADisplayLink 动画期间更新视图
【发布时间】:2023-04-10 12:16:01
【问题描述】:

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

但是正方形看起来是静止的,因为当step() 增加 testX 和 testY 时,Squaresbody 没有得到更新。

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

如何让Squaresbody 与动画一起更新?

我的代码如下,谢谢你的帮助!

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()
    }
}

【问题讨论】:

  • 您是否在任何地方创建 CADisplayLink?你需要让它去某个地方,例如添加修饰符.onAppear { self.animation.createDisplayLink() }
  • 是的,我已经从某个地方调用了 createDisplayLink(),很抱歉造成混淆。动画运行,只是 Squares() 从不更新。

标签: swift swiftui cadisplaylink


【解决方案1】:

这是因为您的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()
        }
    }
}

【讨论】:

  • 这对我不起作用。多么令人沮丧!我正在为 iOS 13.6 使用 Xcode 11.7。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-16
  • 2013-03-29
  • 1970-01-01
  • 1970-01-01
  • 2020-04-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多