azamsharp
azamsharp

Reputation: 20068

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 animation and then fade-out. Above is the fade-out code which removes the UIView instantly instead of having the fade-out effect.

Upvotes: 3

Views: 14392

Answers (6)

Samps
Samps

Reputation: 1049

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()
        }
    })
}

Upvotes: 0

Alexander Kandalov
Alexander Kandalov

Reputation: 51

Swift

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

Upvotes: 4

Heinrisch
Heinrisch

Reputation: 5935

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")

Upvotes: 2

matteodv
matteodv

Reputation: 3982

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];
    }
}];

Upvotes: 4

Paul.s
Paul.s

Reputation: 38728

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

Upvotes: 0

Abizern
Abizern

Reputation: 150575

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]; }];

Upvotes: 25

Related Questions