Circular UIView from nib with animated and non-animated changes

谁说我不能喝 提交于 2020-01-05 04:38:09

问题


I'd like to make a custom view that acts just like a UIView when I make bounds, frame, or transform changes: if I change these things with an assignment, the just change in a single frame, if I change them in a UIView animation block, they animate from their current state to the state I set. I'd like to define the view and it's subviews in IB, and set constraints there.

The following code works coming out of the nib with constraints, and successfully sets bounds/frame/transform with assignment (no animation). But I can't get animation working right.

In particular, the animation of the mask layer seems to go wrong. At present (even though I think layoutSubviews should handle it by matching the view animation) the mask jumps by half the view width/height, then animates back into a centered position as the animation proceeds.

@implementation BubbleView

+ (instancetype)bubbleViewFromNib {
    BubbleView *view = [[NSBundle mainBundle] loadNibNamed:@"BubbleView" owner:nil options:nil][0];
    return view;
}

// this works
- (void)setMaskImageName:(NSString *)name {
    self.maskView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:name]];
}

- (void)layoutSubviews {
    [super layoutSubviews];

    // get current animation for bounds
    CAAnimation *anim = [self.layer animationForKey:@"bounds"];

    [CATransaction begin];
    if(anim) {
        // animating, apply same duration and timing function.
        [CATransaction setAnimationDuration:anim.duration];
        [CATransaction setAnimationTimingFunction:anim.timingFunction];

        self.maskView.frame = self.bounds;
    }
    else {
        // not animating, we should disable implicit animations.
        [CATransaction disableActions];
    }

    self.maskView.frame = self.bounds;
    [CATransaction commit];
}
@end

// calling view controller

// the code in this block doesn't work
[UIView animateWithDuration:1 animations:^{
    //b.transform = CGAffineTransformScale(b.transform, 1.4, 1.4);
    b.frame = CGRectInset(b.frame, -30,-30);
}];

// the same code works fine without animation
//b.frame = CGRectInset(b.frame, -30,-30);

I got the layoutSubviews idea from here https://stackoverflow.com/a/25458725/1272965 and with some help from an earlier question I asked here https://stackoverflow.com/a/45356867/1272965 (which was about not animating when changing these props on simple assignment).

Can you help me make my UIView with a mask work like any view provided by iOS, maintaining constraints and changing frame either animated or not animated? Thanks!

来源:https://stackoverflow.com/questions/45380247/circular-uiview-from-nib-with-animated-and-non-animated-changes

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