Mark
Mark

Reputation: 101

Custom Interactive UIViewController Transition

I would like to implement a custom interactive UIViewController transition that works as follows:

The interaction has to be interactive, so that the transition animation happens alongside the swipe gesture.

I have thought of two ways to implement this:

1) Use a UINavigationController and implement the UINavigationControllerDelegate protocol, setting up the animation and interaction controllers there.

However, this is not a good solution because I don't want stack-based navigation, and don't want to keep a reference to the old child view controller.

2) Implement the UIViewControllerTransitioningDelegate protocol and use the "presentViewController:animated:completion:" method.

However, this method should be used to present a view controller modally, not to replace a currently shown view controller with a new one.

Is there a different way to do this?

Upvotes: 0

Views: 515

Answers (1)

Ahmed Khalaf
Ahmed Khalaf

Reputation: 482

You don't have to own multiple UIViewControllers to reach your target, also it's not recommended, and it'll cause you a lot of memory problems.

The best practice is to have a single UIViewController, and show the user a swiping effect, and change the view's data in the same time.

This code will give a cool swiping effect:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    UISwipeGestureRecognizer *recognizerRight;
    recognizerRight.delegate = self;

    recognizerRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRight:)];
    [recognizerRight setDirection:UISwipeGestureRecognizerDirectionRight];
    [self.view addGestureRecognizer:recognizerRight];


    UISwipeGestureRecognizer *recognizerLeft;
    recognizerLeft.delegate = self;
    recognizerLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeleft:)];
    [recognizerLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
    [self.view addGestureRecognizer:recognizerLeft];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)swipeleft:(UISwipeGestureRecognizer *)swipeGesture
{
    CATransition *animation = [CATransition animation];
    [animation setDelegate:self];
    [animation setType:kCATransitionPush];
    [animation setSubtype:kCATransitionFromRight];
    [animation setDuration:0.50];
    [animation setTimingFunction:
     [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    [self.view.layer addAnimation:animation forKey:kCATransition];

    [self changeViewContent];
}

-(void)swipeRight:(UISwipeGestureRecognizer *)swipeGesture
{
    CATransition *animation = [CATransition animation];
    [animation setDelegate:self];
    [animation setType:kCATransitionPush];
    [animation setSubtype:kCATransitionFromLeft];
    [animation setDuration:0.40];
    [animation setTimingFunction:
     [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    [self.view.layer addAnimation:animation forKey:kCATransition];

    [self changeViewContent];
}

-(void)changeViewContent
{
    // change the view content here
}

Also, if the views you want to swap between them has a totally different UI, then you can use a UITableViewController and change the table cells with every swipe to have the output you want.

I hope that's helping you.

Upvotes: 0

Related Questions