动画在设备上滞后,但在模拟器中不滞后

Posted

技术标签:

【中文标题】动画在设备上滞后,但在模拟器中不滞后【英文标题】:Animation lags on device, but not in Simulator 【发布时间】:2018-04-02 20:49:57 【问题描述】:

我想用 Button 触发 CAAnimation。在操场和模拟器中,这完全符合我的要求。但是,当我在设备上运行相同的代码时,动画只会在短暂的延迟后发生。

显然,该问题仅发生在 ios 11.2.6 上。我更新了我的设备,现在无法再重现该问题。任何人都可以确认或了解它在 iOS 11.2.6 上的工作方式吗?

import UIKit

class MyViewController : UIViewController 
    let animatedView = UIView()

    override func loadView() 
        let view = UIView()
        view.backgroundColor = .white

        // Add a button
        let button = UIButton(type: .system)
        button.frame = CGRect(x: 150, y: 200, width: 200, height: 50)
        button.setTitle("Animate", for: .normal)
        button.addTarget(self, action: #selector(tap), for: .touchUpInside)

        // Set color and frame of the view, that is animated.
        animatedView.backgroundColor = UIColor.blue
        animatedView.frame = CGRect(x: 50, y: 50, width: 50, height: 50)

        // Add the views to the view hierarchy
        view.addSubview(animatedView)
        view.addSubview(button)
        self.view = view
    

    /// On Tap create an animation, that changes the position of the animated view.
    @objc func tap() 
        let originalY = animatedView.layer.position.y
        let animation = CABasicAnimation(keyPath: "position.y")
        animation.fromValue = originalY
        animation.toValue = 300.0
        animation.duration = 1.0
        animatedView.layer.add(animation, forKey: "positionAnimation")
    

【问题讨论】:

另外,您通常不想覆盖loadView,因为这样您就不能从情节提要/XIB 中使用视图控制器。最好覆盖 viewDidLoad 并在那里进行设置。 @GuyKogus 我特别需要CAAnimation,因为我想为图层设置动画。此外,loadView 在这里被覆盖仅用于示例目的,因此它也可以在操场上工作,人们可以轻松地对其进行测试。到目前为止,Apple 还建议使用 UIViewPropertyAnimator 为视图设置动画。 正如您所写的那样,这会使视图的布局超出其视图的边界,这很少是一个好主意。这真的是你的意思吗?通常你不应该直接操作视图的根层。要么操纵视图,要么创建一个子层并操纵它。 我在装有 iOS 11.2.6 的 iPhone 7 和装有 iOS 11.2.2 的 iPhone 6 中测试了您的代码,没有出现明显的延迟。我测试了将您的初始化代码放在 loadView、viewDidLoad 和 viewDidAppear 中(一条评论建议像这样)。这三个案例都是相同的。更新前您的设备可能有问题? > 我已经在 6s+ 和 11.2.6 中测试了您的代码,但没有延迟……在其他版本中也可以正常工作。 根据设备规范,特定设备可能出现问题。 【参考方案1】:

你能在 iOS 11.2.9 上试试这个代码吗,我已经测试了你的代码,它工作正常。

// MARK: Animations
public extension CALayer 

    var ani: CAAnimation 
        let startPointAnim = CABasicAnimation(keyPath: #keyPath(CAGradientLayer.startPoint))
        startPointAnim.fromValue = CGPoint(x: 0, y: 0.0)
        startPointAnim.toValue = CGPoint(x:0, y: 300)

        let endPointAnim = CABasicAnimation(keyPath: #keyPath(CAGradientLayer.endPoint))
        endPointAnim.fromValue = CGPoint(x: 0, y: 0)
        endPointAnim.toValue = CGPoint(x:2, y: 300)

        let animGroup = CAAnimationGroup()
        animGroup.animations = [startPointAnim, endPointAnim]
        animGroup.duration = 1.0
        animGroup.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)            
        return animGroup
    

    func playAnimation(_ anim: SkeletonLayerAnimation, key: String) 
        recursiveSearch(inArray: skeletonSublayers,
                        leafBlock:  add(anim(self), forKey: key) ) 
                            $0.playAnimation(anim, key: key)
        
    

    func stopAnimation(forKey key: String) 
        recursiveSearch(inArray: skeletonSublayers,
                        leafBlock:  removeAnimation(forKey: key) ) 
                            $0.stopAnimation(forKey: key)
        
    

【讨论】:

以上是关于动画在设备上滞后,但在模拟器中不滞后的主要内容,如果未能解决你的问题,请参考以下文章

Mac上的Android模拟器滞后

jQuery 滚动延迟(滞后)在 chrome 上但在 firefox 上平滑

Android 模拟器(来自 Android Studio)滞后

为啥我的 CSS3 动画在 Google Chrome 中不流畅(但在其他浏览器上非常流畅)?

Mysql - 用多个前行(不仅仅是一个)模拟滞后

在 MySQL 中模拟滞后函数