8

I have a superview A and a subview B. In A's drawRect(_:) I do some line drawing that depends on the position and size of subview B. In class A (but not in its drawRect(_:)) I also have an animation block that moves and scales B.

The problem is that the drawing in drawRect(_:) always happens before the animation takes place, either using the final position and size of the subview or using its initial position and size, but never using the intermediate values.

Case 1: drawing uses the final state

The image below is a screen shot of the simulator while the animation that scales the subview is in progress. Note how the lines are already drawn in their final state.

The code for the line drawing is in A's drawRect(_:). This is the code for the animation (it's in class A so self refers to the superview):

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

Case 2: drawing uses the initial state

Looking around for answers I found a suggestion to use self.layer.displayIfNeeded() in place of self.setNeedsDisplay() in the animation block, so I tried this as well

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

but it results in the following. Again, this is a screen shot while the animation that scales up the subview is in progress. Now, the lines are again drawn before the animation starts but using the subview's initial position and size.

enter image description here

I think I understand case 1. The entire animation block is queued for execution but its end result is already computed by the time the animation starts so it's no surprise that drawInRect(_:) is using the final state.

I don't understand case 2 but that's because I have little experience with dealing directly with the view layer.

Either way, the effect I'm looking to achieve is that the lines are drawn to the vertices of the subview while it's being moved and/or scaled. Any suggestions or pointers to documentation are much appreciated. Thanks!

wltrup
  • 778
  • 1
  • 4
  • 14

0 Answers0