iOS中的蹩脚动画

时间:2016-03-25 05:31:52

标签: ios swift animation core-animation

我在iOS中有一个动画,代码如下:

view.layoutIfNeeded()

UIView.animateWithDuration(0.3, delay: 0, options: .CurveEaseInOut, animations: {

    // constraints which are unrelated to drawingResultsController
    self.leadingSpaceToContainerViewConstraint.constant = 0
    self.trailingSpaceToContainerViewConstraint.constant = 0

    // This controller doesn't have any constraints
    drawingResultsController.view.frame.origin = CGPoint(x: self.view.bounds.width, y: 0)
    self.view.layoutIfNeeded()

}, completion: { finished in

    drawingResultsController.view.removeFromSuperview()
    drawingResultsController.removeFromParentViewController()
    drawingResultsController.didMoveToParentViewController(nil)
})
然而,动画看起来并不流畅。它无论如何都不可怕,但你绝对可以说它的速度低于30 fps。有没有人知道为什么会这样?我已经验证了一切都在主线上。

额外细节:

父控制器的视图有一个子视图固定在它的超视图(主视图)的边缘,这些是上面看到的约束。该子视图包含控制器的主视图(即,当 drawingResultsController 滑入和滑出屏幕时,它可以创建视差效果)。 drawingResultsController 是添加为主视图子视图的子视图控制器,它没有任何约束。它可以滑入和滑出屏幕,这是将其滑出的代码。

这样,约束移动的视图是 drawingResultsController 视图的兄弟。两者都是主视图的直接子视图。

编辑:

将动画缩小到这个

UIView.animateWithDuration(0.3, delay: 0, options: .CurveEaseInOut,    animations: {

    drawingResultsController.view.frame.origin = CGPoint(x: self.view.bounds.width, y: 0)

}, completion: nil)

稍微改善帧速率,但它仍然是一个问题。设置更长的动画时间时更明显。在动画时,CPU和内存的使用看起来完全正常。

谢谢

2 个答案:

答案 0 :(得分:1)

我有一个类似的问题,事实证明它是通过重启设备解决的。

然而,这个问题似乎也可以通过让CADisplayLink更新随机图层来解决,该随机图层是窗口层次结构的一部分。我注意到了,因为我们的应用程序中运行了一个动画,该动画由CADisplayLink触发并解决了应用程序中其他地方的所有慢动画!

下面的黑客解决了这个问题。将代码添加到主窗口类(假设您为主窗口使用自定义UIWindow子类):

//Hack for slow animation problem that occurs after long uptime of the device, updating a view's layer position that's in the view hierarchy using a display link solves the slow animations.

@property (nonatomic, strong) UIView *dummyView;
@property (nonatomic, strong) CADisplayLink *displayLink;

- (void)enableSlowAnimationHack {
    if (self.dummyView == nil) {
        self.dummyView = [[UIView alloc] initWithFrame:CGRectZero];
        [self addSubview:self.dummyView];
    }
    if (self.displayLink == nil) {
        self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animateWithLink:)];
        [self.displayLink addToRunLoop: [NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
    }
}

- (void)animateWithLink:(CADisplayLink *)sender {
    self.dummyView.layer.position = CGPointMake((arc4random() % 100) / 100.0, (arc4random() % 100) / 100.0);
}

答案 1 :(得分:0)

显然它自己解决了。它没有多大意义,因为它发生在模拟器和设备中,并且没有代码被更改。