Combining NSLayoutConstraints with supported CALayer views is not animating correctly

I have an automatic layout setting with animation that changes the value of the NSLayoutContraint constant

// set the slide in view initial height to zero self.adViewHeightConstraint = [NSLayoutConstraint constraintWithItem:self.adContainerView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:0.0]; [self.view addConstraint:self.adViewHeightConstraint]; // later, set the slid in view height to non-zero double delayInSeconds = 3.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ self.adViewHeightConstraint.constant = 100; [UIView animateWithDuration:2.5 animations:^{ [self.view layoutIfNeeded]; }]; }); 

This correctly animates the view sizes that I have, and therefore works correctly. The problem that I see, however, is that some of the user layers supported by me do not redraw for an animation duration of 2.5 seconds.

The behavior I see is that a custom layer that supports the views is requested for the final position at the beginning of the animation, then a transform is applied that stretches the view for the duration of the animation until it eventually looks right.

enter image description here

What these 4 shots show is a red bar that enlivens, and then the two blue images are compressed in height each to account for the size reduction. The layer knows how to draw for each border change, but the animation does not ask him to redraw at each step of the animation ... only at the beginning. That's why the black circle looks like an oval - these are the same two halves as image # 4, but stretched.

The custom subclass of CAlayer has one overridden method: drawInContext: and YES set to the needsDisplayOnBoundsChange layer.

So the question remains ... How can I tell this NSLayoutConstraints animation to redraw the views throughout the animation?

+4
source share
1 answer

This is a known problem (if you understand it, you will see a couple of good hits, although I think that this answer, although admittedly focuses on different symptoms, is the most clear answer that I have seen so far, describing the problem of scaling UIView during animation ... this is an old answer, but still applicable, I think).

The simplest solution, IMHO, is to put a layer in a view that will not change during the animation (for example, a new fixed-size view, the restrictions of which allow you to focus on your view of the content, but do not change how your content does it). In this way, you can enjoy constraint-based animations, but not lose your own format and size.

+1
source

Source: https://habr.com/ru/post/1494604/


All Articles