Eduardo Russo
Eduardo Russo

Reputation: 4219

Remove from superview AND enable user interaction

I'm doing some custom animations to change views in a single method. I already removed "fromView" from superView using [UIView setAnimationDidStopSelector:@selector(removeFromSuperview)], but I also want to enable user interaction after the end of the animation.

Here's my code:

-(void) switchFrom:(UIViewController*) fromViewController To:(UIViewController*) toViewController usingAnimation:(int) animation{
    UIView *fromView = fromViewController.view;
    UIView *toView = toViewController.view;
    /*************** SET ALL DEFAULT TRANSITION SETTINGS ***************/
    // Get the current view frame, width and height
    CGRect pageFrame = fromView.frame;
    CGFloat pageWidth = pageFrame.size.width;
    
    // Create the animation
    [UIView beginAnimations:nil context:nil];
    
    // Create the delegate, so the "fromView" is removed after the transition
    [UIView setAnimationDelegate: fromView];
    [UIView setAnimationDidStopSelector:@selector(removeFromSuperview)];
    
    // Set the transition duration
    [UIView setAnimationDuration: 0.4];

    /*************** IT DOESN'T WORK AT ALL ***************/
    [toView setUserInteractionEnabled:NO];
    [UIView setAnimationDelegate: toView];
    [UIView setAnimationDidStopSelector:@selector(setUserInteractionEnabled:)];
    [toView setUserInteractionEnabled:YES];

    // Add the "toView" as subview of "fromView" superview
    [fromView.superview addSubview:toView];
    switch (animation) {
        case AnimationPushFromRigh:{
            // Position the "toView" to the right corner of the page            
            toView.frame = CGRectOffset(pageFrame, pageWidth,0);
            
            // Animate the "fromView" to the left corner of the page
            fromView.frame = CGRectOffset(pageFrame, -pageWidth,0);
            
            // Animate the "toView" to the center of the page
            toView.frame = pageFrame;
            
            // Animate the "fromView" alpha
            fromView.alpha = 0;
            
            // Set and animate the "toView" alpha
            toView.alpha = 0;
            toView.alpha = 1;

            // Commit the animation
            [UIView commitAnimations];
        }
        .
        .
        .

Any idea how can I call this two methods in setAnimationDidStopSelector and actually make them work together?

EDIT 1

Tried @safecase code like this, replacing this commented block:

/*************** IT DOESN'T WORK AT ALL ***************
[toView setUserInteractionEnabled:NO];
[UIView setAnimationDelegate: toView];
[UIView setAnimationDidStopSelector:@selector(setUserInteractionEnabled:)];
[toView setUserInteractionEnabled:YES];
*************** IT DOESN'T WORK AT ALL ***************/
// Remove the interaction
[toView setUserInteractionEnabled:NO];
[fromView setUserInteractionEnabled:NO];
// Create the animation
[UIView animateWithDuration:0.4 animations:^{
    [fromView performSelector:@selector(removeFromSuperview)];
    }
    completion:^(BOOL finished){
        [UIView animateWithDuration:0.4 
        animations:^{ 
            C6Log(@"finished");
            [toView performSelector: @selector(setUserInteractionEnabled:)];
        }];
    }];

The "toView" is removed instead of the "fromView" is removed :( The buttons continue to be interactive during the animation

Upvotes: 1

Views: 783

Answers (5)

Eduardo Russo
Eduardo Russo

Reputation: 4219

I ended up creating a Category extension to UIView… and it finally works!

UIView+Animated.h code

#import <UIKit/UIKit.h>

@interface UIView (Animated)

- (void) finishedAnimation;

@end

UIView+Animated.m code

#import "UIView+Animated.h"

@implementation UIView (Animated)

- (void) finishedAnimation{
    C6Log(@"FinishedAnimation!");
    [self removeFromSuperview];
    [[UIApplication sharedApplication] endIgnoringInteractionEvents];
}

@end

Then, I #imported this extension in my coordinating controller:

C6CoordinatingController.h partial code

#import "UIView+Animated.h"

And called the selector in setAnimationDidStopSelector:

C6CoordinatingController.m partial code

// Create the delegate, so the "fromView" is removed after the transition
[UIView setAnimationDelegate: fromView];

// Ignore interaction events during the animation
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];

// Set the transition duration
[UIView setAnimationDuration: 0.4];

// Call UIView+Animated "finishedAnimation" method when animation stops
[UIView setAnimationDidStopSelector:@selector(finishedAnimation)];

So, I ended up using @jaydee3 and @Mundi concepts and it works like a charm!

Thank you guys!

Upvotes: 0

calimarkus
calimarkus

Reputation: 9977

Do you know beginIgnoringInteractionEvents and endIgnoringInteractionEvents? Normally, if you don't want any userInteraction during an animation, you would use those.

Anyway you still need correct callbacks to trigger them.

Upvotes: 2

ganesh manoj
ganesh manoj

Reputation: 977

I think u can use to enable user interaction
self.view.userInteractionEnabled=NO;

Upvotes: 0

Paresh Navadiya
Paresh Navadiya

Reputation: 38239

You can use this:

 [UIView animateWithDuration:0.4

 animations:^{ [self performSelector:@selector(removeFromSuperview)]; // other code here}

 completion:^(BOOL finished){ [UIView animateWithDuration:0.4

 animations:^{ [self performSelector:@selector(setUserInteractionEnabled:)]; //other code here}]; }];

Hope helpful.

Upvotes: 1

Mundi
Mundi

Reputation: 80265

You need to define your own method, e.g. remove: and pass that as the selector. In the method, just use the passed UIView to remove it.

-(void)remove:(id)sender {
   UIView *v = (UIView*)sender;
   [v removeFromSuperview];
}

Upvotes: 1

Related Questions