强制UIView在动画块内重绘其内容

时间:2015-04-22 16:49:00

标签: ios swift animation uiview uiviewanimation

我有一个超级视图A和一个子视图B.在A drawRect(_:)中我做了一些线图,这取决于子视图B的位置和大小。在A类中(但不在其drawRect(_:)中)我还有一个移动和缩放B的动画块。

问题在于drawRect(_:)中的绘图总是在之前动画发生,使用最终位置和子视图的大小或使用它初始位置和大小,但从不使用中间值。

案例1:绘图使用最终状态

下图是模拟器的屏幕截图,而缩放子视图的动画正在进行中。注意线条是如何在最终状态下绘制的。

线条图的代码位于A drawRect(_:)中。这是动画的代码(它在A类中,因此self指的是超级视图):

UIView.animateWithDuration(3.0, delay: 0.5,
    options: UIViewAnimationOptions.CurveLinear,
    animations: {

        [unowned self] in
        self.subviewWidthConstraint.constant = 0.75 * CGRectGetWidth(self.bounds)

        self.layoutIfNeeded()
        self.setNeedsDisplay() // this has no effect since self's bounds don't change

    }) { (completed) -> Void in }

enter image description here

案例2:绘图使用初始状态

寻找答案我发现建议在动画块中使用self.layer.displayIfNeeded()代替self.setNeedsDisplay(),所以我也尝试了这个

func animateFrame()
{
    UIView.animateWithDuration(3.0, delay: 0.5,
        options: UIViewAnimationOptions.CurveLinear,
        animations: {

            [unowned self] in
            self.subviewWidthConstraint.constant = 0.75 * CGRectGetWidth(self.bounds)

            self.layoutIfNeeded()
            self.layer.displayIfNeeded() // the only difference is here

        }) { (completed) -> Void in }
}

但结果如下。同样,这是一个屏幕截图,而放大子视图的动画正在进行中。现在,在动画开始之前再次绘制线条,但使用子视图的初始位置和大小。

enter image description here

我想我理解了案例1.整个动画块排队等待执行,但最终结果已经在动画开始时计算出来,所以drawInRect(_:)使用最终状态就不足为奇了。

我不理解案例2,但那是因为我没有直接处理视图层的经验。

无论哪种方式,我想要实现的效果是线条被绘制到子视图的顶点,而它被移动和/或缩放。任何建议或文档指针都非常感谢。谢谢!

0 个答案:

没有答案