开发者

Remove UIView from super view after animation ended

I am animating a UIView (alpha) property and I want that after the animation has finished I can remove it from the super view.

    -(void) hideOverlayView
{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:1.0];

    [topView setAlpha:0];

    [UIView commitAnimations];

}

One option is to use performSelector with delay option but is there a more compact way?

UPDATE 1:

Why does this code remove the view instantly?

[UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationDelegate:topView];
    [UIView setAnimationDidStopSelector:@selector(removeFromSuperview)];

    [topView setAlpha:0];

    [UIView commitAnimations];

I should mention that first I am doing a fade-in anima开发者_Python百科tion and then fade-out. Above is the fade-out code which removes the UIView instantly instead of having the fade-out effect.


Straight from the UIView docs

[UIView animateWithDuration:0.2
     animations:^{view.alpha = 0.0;}
     completion:^(BOOL finished){ [view removeFromSuperview]; }];

Or in your specific case:

[UIView animateWithDuration:1.0
    animations:^{topView.alpha:0.0;}
    completion:^(BOOL finished){ [topView removeFromSuperview]; }];


You can use blocks to perform this kind of action ;)
Something like this:

[UIView animateWithDuration:1.0 animations:^{
    topView.alpha = 1.0; topView.alpha = 0.0;
} completion:^(BOOL success) {
    if (success) {
        [topView removeFromSuperview];
    }
}];


Swift

UIView.animate(withDuration: 0.5, animations: {
        self.exampleView.alpha = 0.0
        }, completion: { (finished: Bool) in
          self.exampleView.removeFromSuperview() 
        })


If you are using CAKeyframeAnimation or similar you need to assign a delegate to the animation.

I created this class as the being the delegate (Swift 3):

class AnimationDelegate: NSObject, CAAnimationDelegate {
    typealias AnimationCallback = (() -> Void)

    let didStart: AnimationCallback?
    let didStop: AnimationCallback?

    init(didStart: AnimationCallback?, didStop: AnimationCallback?) {
        self.didStart = didStart
        self.didStop = didStop
    }

    internal func animationDidStart(_ anim: CAAnimation) {
        didStart?()
    }

    internal func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        didStop?()
    }
}

Then I can use that class like this:

let animateView = UIView()
let anim = CAKeyframeAnimation(keyPath: "position")
anim.delegate = AnimationDelegate(
            didStart: nil,
            didStop: {
                heart.removeFromSuperview()
        })
animateView.layer.add(anim, forKey: "animate position along path")


If you are targeting > iOS 4 then you should be looking at blocks. Otherwise look at the documentation for UIView specifically at setAnimationDelegate:


If you have view which is class variable and can be recreated to fade it out and afterwards to on with new data displayed, you might need something like this:

Swift 4

func removeView(animated: Bool) {
    guard let index = subviews.index(of: viewToRemove) else { return }
    animated ? removeSubViewWithFading(from: index) :
        viewToRemove.removeFromSuperview()
}

private func removeSubViewWithFading(from index: Int) {
    let view = self.subviews[index]
    UIView.animate(withDuration: 1, animations: {
        view.alpha = 0
    }, completion: { _ in
        if self.subviews.count > index {
            view.removeFromSuperview()
        }
    })
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜