user230949
user230949

Reputation: 1119

Animating removeFromSuperview

I'd like to animate the transition from a subview back to the super view.

I display the subview using:

[UIView beginAnimations:@"curlup" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:.5];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
[self.view addSubview:self.mysubview.view];
[UIView commitAnimations];

The above works fine. It's going back to the super view that I don't get any animation:

[UIView beginAnimations:@"curldown" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:.5];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view cache:YES];
[self.view removeFromSuperview];
[UIView commitAnimations];

Is there something different I should be doing to get the subview to animate when removed?

Upvotes: 40

Views: 39496

Answers (5)

JosephH
JosephH

Reputation: 37495

If you're targeting iOS 4.0 upwards you can use animation blocks instead:

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

(above code comes from Apple's UIView documentation)

Upvotes: 112

De Zheng
De Zheng

Reputation: 51

Example below:

func removeSpinningGear(cell: LocalSongsCollectionViewCell) {
    UIView.animate(withDuration: 1.0, delay: 0.0, options: UIView.AnimationOptions.curveLinear, animations: {
        cell.spinningGearBtn.alpha = 0.0
    }) { _ in
        cell.spinningGearBtn.removeFromSuperview()
    }
}

Upvotes: 0

nalexn
nalexn

Reputation: 10791

Although approach with sending removeFromSuperview message from animation completion block works fine for most cases, sometimes there is no way to prevent a view from immediate removal from view hierarchy.

For example, MKMapView removes its subviews after it receives message removeAnnotations, and there is no "animated" alternative for this message in the API.

Nonetheless the following code allows you to do whatever you like with a visual clone of a view after it's been removed from superview or even deallocated:

UIView * snapshotView = [view snapshotViewAfterScreenUpdates:NO];
snapshotView.frame = view.frame;
[[view superview] insertSubview:snapshotView aboveSubview:view];

// Calling API function that implicitly triggers removeFromSuperview for view
[mapView removeAnnotation: annotation];

// Safely animate snapshotView and release it when animation is finished
[UIView animateWithDuration:1.0
                     snapshotView.alpha = 0.0;
                 }
                 completion:^(BOOL finished) {
                     [snapshotView removeFromSuperview];
                 }];

Upvotes: 6

Tal Haham
Tal Haham

Reputation: 1628

JosephH answer in Swift:

UIView.animateWithDuration(0.2, animations: {view.alpha = 0.0}, 
                                completion: {(value: Bool) in
                                              view.removeFromSuperview()
                                            })

Upvotes: 27

newacct
newacct

Reputation: 122429

I think you need to do forView:self.view.superview instead, to be consistent with what you are doing when you are adding, because in this case the self.view is the child, and so you would need to do it on the parent.

Upvotes: 28

Related Questions