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()
}
})
}
精彩评论