Forcing a UIView to redraw content inside an animation block

I have supervisor A and subview B. In A drawRect(_:) I draw a few lines that depend on the position and size of the sub-view B. In class A (but not in its drawRect(_:) ) I also have an animation block which moves and scales B.

The problem is that drawing drawRect(_:) always happens before the animation happens, either using the end position and size of the subtitle, or using its starting position and size, but never using intermediate values.

Case 1: the drawing uses the final state

The screenshot below is a screenshot of the simulator, while the animation that scales the preview is executed. Notice how the lines are already crossed out in the final state.

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

 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 bounds don't change }) { (completed) -> Void in } 

enter image description here

Case 2: the drawing uses the initial state

Looking back at the answers, I found a suggestion to use self.layer.displayIfNeeded() instead 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 this leads to the following. Again, this is a screenshot when an animation that scales the preview is executed. Now the lines are drawn again before the start of the animation, but using the starting position and size of the subview.

enter image description here

I think I understand case 1. The entire animation block is queued for execution, but its final result is already calculated by the time the animation starts, so it is not surprising that drawInRect(_:) uses the final state.

I do not understand case 2, but this is because I have little experience working directly with the presentation level.

In any case, the effect I want to achieve is that the lines are drawn on the tops of the subview , and are moved and / or scaled. Any suggestions or pointers to documentation are greatly appreciated. Thanks!

+5
source share

All Articles