Combining NSLayoutConstraints with CALayer backed views does not animate correctly

自作多情 提交于 2019-12-22 08:51:35

问题


I have an auto layout setup with an animation that alters a NSLayoutContraint constant value

// set the slide in view's 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's 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 animated the sizes of the views I have and thus, works correctly. The problem I am seeing, however, is that some custom layer backed views I have are not being redrawn over the duration of the 2.5 sec animation.

The behavior I am seeing is that the custom layer backed views are asked to draw for the final position at the beginning of the animation, then a transform is applied that stretches the view over the duration of the animation until it eventually looks correct.

What these 4 shots show is the red bar animating up, then the two blue views shrinking in height each to accommodate the size reduction. The layer knows how to draw itself correctly for each bounds change, but the animation is not asking it to redraw at each step of the animation... only at the beginning. This is why the black circle looks like an oval — it is the same 2 halves as image #4 but stretched.

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

Thus, the question remains... How can I tell this animation of NSLayoutConstraints to let the views redraw during the entire animation?


回答1:


This is a known issue (if you google it you'll see a couple of good hits, though I think this answer, while admittedly focusing of different symptoms, is the most articulate answer I've seen thus far describing the problem UIView scaling during animation ... it's an old answer, but still applicable, I believe).

The easiest solution, IMHO, would be to put the layer in a view that doesn't resize upon animation (e.g. a new view, of fixed size, whose constraints keep it centered on your content view, but doesn't change size as your content view does). That way, you can enjoy the constraints-based animations, but not lose your custom layer's aspect ratio/size.



来源:https://stackoverflow.com/questions/17982834/combining-nslayoutconstraints-with-calayer-backed-views-does-not-animate-correct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!