[Ios] ナビゲーションベースのアプリでプッシュとポップのアニメーションを変更する方法


Answers

これは私がいつもこの作業を完了した方法です。

プッシュの場合:

MainView *nextView=[[MainView alloc] init];
[UIView  beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[self.navigationController pushViewController:nextView animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
[nextView release];

ポップスの場合:

[UIView  beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:NO];
[UIView commitAnimations];

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelay:0.375];
[self.navigationController popViewControllerAnimated:NO];
[UIView commitAnimations];


私はまだこの点から多くのフィードバックを得ていますので、私は先に進んで、アニメーションブロックを使用するようにアップデートします。これはAppleがアニメーションをやり遂げるために推奨する方法です。

プッシュの場合:

MainView *nextView = [[MainView alloc] init];
[UIView animateWithDuration:0.75
                         animations:^{
                             [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                             [self.navigationController pushViewController:nextView animated:NO];
                             [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
                         }];

ポップスの場合:

[UIView animateWithDuration:0.75
                         animations:^{
                             [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                             [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:NO];
                         }];
[self.navigationController popViewControllerAnimated:NO];
Question

ナビゲーションベースのアプリケーションがあり、プッシュアニメーションとポップアニメーションのアニメーションを変更したいと考えています。 どうすればいい?




プライベートコールを使用することは、アップルがこれを行うアプリケーションを承認しなくなったため、悪い考えです。 たぶんあなたはこれを試すことができます:

//Init Animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: 0.50];


[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.navigationController.view cache:YES];

//Create ViewController
MyViewController *myVC = [[MyViewController alloc] initWith...];

[self.navigationController pushViewController:myVC animated:NO];
[myVC release];

//Start Animation
[UIView commitAnimations];



@Magnusの答えはSwift(2.0)のためだけです。

    let transition = CATransition()
    transition.duration = 0.5
    transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    transition.type = kCATransitionPush
    transition.subtype = kCATransitionFromTop
    self.navigationController!.view.layer.addAnimation(transition, forKey: nil)
    let writeView : WriteViewController = self.storyboard?.instantiateViewControllerWithIdentifier("WriteView") as! WriteViewController
    self.navigationController?.pushViewController(writeView, animated: false)

いくつかのsidenotes:

これはSegueでも同様に行うことができます。これをprepareForSegueまたはshouldPerformSegueWithIdentifier実装するだけshouldPerformSegueWithIdentifierただし 、これによってデフォルトのアニメーションも保持されます。 これを修正するには、ストーリーボードに移動してSegueをクリックし、 'Animates'のチェックを外します。 しかし、これはあなたのアプリをIOS 9.0以上(Xcode 7でやった時代以上)に制限します。

セグの場合、最後の2行を次のように置き換えます。

self.navigationController?.popViewControllerAnimated(false)

私が偽を設定しても、それは無視されます。




See my answer to this question for a way to do it in far fewer lines of code. This method allows you to animate a pseudo-"Push" of a new view controller any way you like, and when the animation is done it sets up the Navigation Controller just as if you had used the standard Push method. My example lets you animate either a slide-in from the left or from the right. Code repeated here for convenience:

-(void) showVC:(UIViewController *) nextVC rightToLeft:(BOOL) rightToLeft {
    [self addChildViewController:neighbor];
    CGRect offscreenFrame = self.view.frame;
    if(rightToLeft) {
        offscreenFrame.origin.x = offscreenFrame.size.width * -1.0;
    } else if(direction == MyClimbDirectionRight) {
        offscreenFrame.origin.x = offscreenFrame.size.width;
    }
    [[neighbor view] setFrame:offscreenFrame];
    [self.view addSubview:[neighbor view]];
    [neighbor didMoveToParentViewController:self];
    [UIView animateWithDuration:0.5 animations:^{
        [[neighbor view] setFrame:self.view.frame];
    } completion:^(BOOL finished){
        [neighbor willMoveToParentViewController:nil];
        [neighbor.view removeFromSuperview];
        [neighbor removeFromParentViewController];
        [[self navigationController] pushViewController:neighbor animated:NO];
        NSMutableArray *newStack = [[[self navigationController] viewControllers] mutableCopy];
        [newStack removeObjectAtIndex:1]; //self, just below top
        [[self navigationController] setViewControllers:newStack];
    }];
}



I am not aware of any way you can change the transition animation publicly.

If the "back" button is not necessary you should use modal view controllers to have the "push from bottom" / "flip" / "fade" / (≥3.2)"page curl" transitions.

On the private side, the method -pushViewController:animated: calls the undocumented method -pushViewController:transition:forceImmediate: , so eg if you want a flip-from-left-to-right transition, you can use

[navCtrler pushViewController:ctrler transition:10 forceImmediate:NO];

You can't change the "pop" transition this way, however.




ちょうど使用する:

ViewController *viewController = [[ViewController alloc] init];

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
navController.navigationBarHidden = YES;

[self presentViewController:navController animated:YES completion: nil];
[viewController release];
[navController release];



ナビゲーションベースのアプリケーションでプッシュとポップのアニメーションを変更する方法...

2018年、「最終回答!」

はじめに あなたはおそらくAndroidから、iOS開発の初心者です。 非常に混乱して、Appleは簡単に使用できる2つのトランジションを提供しています。 これらは "クロスフェード"と "フリップ"です。 現在、誰も使用していない "クロスフェード"と "フリップ"は、すべてのコンピューティングで最も無駄な2つのトランジションです。 「滑り落ちる」などの最も一般的なトランジションを実行したい場合は、大量の作業を行う必要があります。 その仕事は、この記事で説明されています!

  • まず、アップルが提供する2つのアニメの1つ(クロスフェード、フリップ) を使用したい場合は、単純です。上記の@PeterDeWeeseのソリューションを使用します。

  • 第二に、古いすばやく汚れたCATransitionクイックフィックスがあります。 これについてはここで詳しく説明します 。 実際には機能しませんし、現実的な解決策ではありません。

それ以外の場合は、驚くべきことに、 完全なカスタムトランジションを実行するように努力する必要があります。

繰り返す:

たとえ最も簡単で最も一般的なムーブオーバー/ムーブオフトランジションが必要な場合でも、完全なカスタムトランジションを実装する必要があります。

ここでそれを行う方法です...

1.カスタムUIViewControllerAnimatedTransitioningが必要です。

  1. popStyleのような自分のブールが必要popStyle 。 (それが飛び出しているのか、それとも飛び出していますか?)

  2. あなたは、 transitionDuration (簡単な)とメイン呼び出しanimateTransition

  3. 実際には、 animateTransition内部に2つの異なるルーチンを記述する必要があります。 1つはプッシュ、もう1つはポップです。 おそらく、 animatePushanimatePop名前を付けます。 animateTransition内部で、 popStyleを2つのルーチンに分岐するだけです

  4. 以下の例では単純な移動/移動を行います

  5. あなたのanimatePushanimatePopルーチンで。 あなたは "見るから"と "見る"必要があります。 (How-toはこの例に示されています)。

  6. あなたがしなければならない主なことは、実際には、新しい "to"ビューのためのaddSubviewを追加することです。

  7. あなたはあなたのアニメの終わりにcompleteTransitionを呼び出さなければなりません

そう ..

  class SimpleOver: NSObject, UIViewControllerAnimatedTransitioning {

        var popStyle: Bool = false

        func transitionDuration(
            using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
            return 0.20
        }

        func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

            if popStyle {

                animatePop(using: transitionContext)
                return
            }

            let fz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
            let tz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!

            let f = transitionContext.finalFrame(for: tz)

            let fOff = f.offsetBy(dx: f.width, dy: 55)
            tz.view.frame = fOff

            transitionContext.containerView.insertSubview(tz.view, aboveSubview: fz.view)

            UIView.animate(
                withDuration: transitionDuration(using: transitionContext),
                animations: {
                    tz.view.frame = f
            }, completion: {_ in 
                    transitionContext.completeTransition(true)
            })
        }

        func animatePop(using transitionContext: UIViewControllerContextTransitioning) {

            let fz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
            let tz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!

            let f = transitionContext.initialFrame(for: fz)
            let fOffPop = f.offsetBy(dx: f.width, dy: 55)

            transitionContext.containerView.insertSubview(tz.view, belowSubview: fz.view)

            UIView.animate(
                withDuration: transitionDuration(using: transitionContext),
                animations: {
                    fz.view.frame = fOffPop
            }, completion: {_ in 
                    transitionContext.completeTransition(true)
            })
        }
    }

その後 ...

2.ビューコントローラで使用します。

「最初の」ビューコントローラでこれを行うだけでよいことに注意してください。

一番上にポップするものは何もしません。 簡単です。

あなたのクラス...

class SomeScreen: UIViewController {
}

になる...

class FrontScreen: UIViewController,
        UIViewControllerTransitioningDelegate, UINavigationControllerDelegate {

    let simpleOver = SimpleOver()


    override func viewDidLoad() {

        super.viewDidLoad()
        navigationController?.delegate = self
    }

    func navigationController(
        _ navigationController: UINavigationController,
        animationControllerFor operation: UINavigationControllerOperation,
        from fromVC: UIViewController,
        to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {

        simpleOver.popStyle = (operation == .pop)
        return simpleOver
    }
}

それでおしまい。

押してポップアップを通常のように正確に行います。 プッシュする ...

let n = UIStoryboard(name: "nextScreenStoryboardName", bundle: nil)
          .instantiateViewController(withIdentifier: "nextScreenStoryboardID")
          as! NextScreen
navigationController?.pushViewController(n, animated: true)

それをポップするには、次の画面でそれをしたい場合は、

class NextScreen: TotallyOrdinaryUIViewController {

    @IBAction func userClickedBackOrDismissOrSomethingLikeThat() {

        navigationController?.popViewController(animated: true)
    }
}

それは "それほど単純な"ものです:O




While all the answers here are great and most work very well, there is a slightly simpler method which achieves the same effect...

For Push:

  NextViewController *nextViewController = [[NextViewController alloc] init];

  // Shift the view to take the status bar into account 
  CGRect frame = nextViewController.view.frame;
  frame.origin.y -= 20;
  frame.size.height += 20;
  nextViewController.view.frame = frame;

  [UIView transitionFromView:self.navigationController.topViewController.view toView:nextViewController.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromRight completion:^(BOOL finished) {
    [self.navigationController pushViewController:nextViewController animated:NO];
  }];

For Pop:

  int numViewControllers = self.navigationController.viewControllers.count;
  UIView *nextView = [[self.navigationController.viewControllers objectAtIndex:numViewControllers - 2] view];

  [UIView transitionFromView:self.navigationController.topViewController.view toView:nextView duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft completion:^(BOOL finished) {
    [self.navigationController popViewControllerAnimated:NO];
  }];}



Based on answer updated for swift 4

For push UIViewController

let yourVC = self.storyboard?.instantiateViewController(withIdentifier: "yourViewController") as! yourViewController
    UIView.animate(withDuration: 0.75, animations: {() -> Void in
    UIView.setAnimationCurve(.easeInOut)
    self.navigationController?.pushViewController(terms, animated: true)
    UIView.setAnimationTransition(.flipFromRight, for: (self.navigationController?.view)!, cache: false)
})

For Pop

UIView.animate(withDuration: 0.75, animations: {() -> Void in
    UIView.setAnimationCurve(.easeInOut)
    UIView.setAnimationTransition(.flipFromLeft, for: (self.navigationController?.view)!, cache: false)
})
navigationController?.popViewController(animated: false)



私は最近、似たようなことをしようとしていました。 私はUINavigationControllerのスライディングアニメーションが気に入らないと決めたのですが、UIViewがあなたにカールやそのようなものを与えるアニメーションもしたくありませんでした。 私はプッシュまたはポップ時にビュー間でクロスフェードを行いたいと思っていました。

そこでの問題は、ビューが文字通り現在のビューの上にビューを表示したりポップしたりするため、フェードが機能しないという事実があります。 私の新しいビューを取得し、それをUIViewControllerのスタック上の現在のトップビューにサブビューとして追加することになった解決策。 私は0のアルファでそれを加えてから、クロスフェードします。 アニメーションシーケンスが終了すると、ビューをアニメーション化せずにスタックにプッシュします。 私は古いTopViewに戻り、私が変更したものをクリーンアップします。

その複雑さは、それよりも少し複雑です。なぜなら、遷移を正しく見せるために調整しなければならないnavigationItemがあるからです。 また、回転を行う場合は、ビューをサブビューとして追加するときにフレームサイズを調整して、画面に正しく表示されるようにする必要があります。 ここで私が使ったコードのいくつかがあります。 私はUINavigationControllerをサブクラス化し、プッシュメソッドとポップメソッドをオーバーライドしました。

-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
      UIViewController *currentViewController = [self.viewControllers lastObject];
      //if we don't have a current controller, we just do a normal push
      if(currentViewController == nil)
      {
         [super pushViewController:viewController animated:animated];
         return;
      }
      //if no animation was requested, we can skip the cross fade
      if(!animation)
      {
         [super pushViewController:viewController animated:NO];
         return;
      }
      //start the cross fade.  This is a tricky thing.  We basically add the new view
//as a subview of the current view, and do a cross fade through alpha values.
//then we push the new view on the stack without animating it, so it seemlessly is there.
//Finally we remove the new view that was added as a subview to the current view.

viewController.view.alpha = 0.0;
//we need to hold onto this value, we'll be releasing it later
    NSString *title = [currentViewController.title retain];

//add the view as a subview of the current view
[currentViewController.view addSubview:viewController.view];
[currentViewController.view bringSubviewToFront:viewController.view];
UIBarButtonItem *rButtonItem = currentViewController.navigationItem.rightBarButtonItem;
UIBarButtonItem *lButtonItem = currentViewController.navigationItem.leftBarButtonItem;

NSArray *array = nil;

//if we have a right bar button, we need to add it to the array, if not, we will crash when we try and assign it
//so leave it out of the array we are creating to pass as the context.  I always have a left bar button, so I'm not checking to see if it is nil. Its a little sloppy, but you may want to be checking for the left BarButtonItem as well.
if(rButtonItem != nil)
    array = [[NSArray alloc] initWithObjects:currentViewController,viewController,title,lButtonItem,rButtonItem,nil];
else {
    array = [[NSArray alloc] initWithObjects:currentViewController,viewController,title,lButtonItem,nil];
}

//remove the right bar button for our transition
[currentViewController.navigationItem setRightBarButtonItem:nil animated:YES];
//remove the left bar button and create a backbarbutton looking item
//[currentViewController.navigationItem setLeftBarButtonItem:nil animated:NO];

//set the back button
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:title style:kButtonStyle target:self action:@selector(goBack)];
[currentViewController.navigationItem setLeftBarButtonItem:backButton animated:YES];
[viewController.navigationItem setLeftBarButtonItem:backButton animated:NO];
[backButton release];

[currentViewController setTitle:viewController.title];

[UIView beginAnimations:@"push view" context:array];
[UIView setAnimationDidStopSelector:@selector(animationForCrossFadePushDidStop:finished:context:)];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.80];
[viewController.view setAlpha: 1.0];
[UIView commitAnimations];
}

-(void)animationForCrossFadePushDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{

UIViewController *c = [(NSArray*)context objectAtIndex:0];
UIViewController *n = [(NSArray*)context objectAtIndex:1];
NSString *title     = [(NSArray *)context objectAtIndex:2];
UIBarButtonItem *l = [(NSArray *)context objectAtIndex:3];
UIBarButtonItem *r = nil;
//not all views have a right bar button, if we look for it and it isn't in the context,
//we'll crash out and not complete the method, but the program won't crash.
//So, we need to check if it is there and skip it if it isn't.
if([(NSArray *)context count] == 5)
    r = [(NSArray *)context objectAtIndex:4];

//Take the new view away from being a subview of the current view so when we go back to it
//it won't be there anymore.
[[[c.view subviews] lastObject] removeFromSuperview];
[c setTitle:title];
[title release];
//set the search button
[c.navigationItem setLeftBarButtonItem:l animated:NO];
//set the next button
if(r != nil)
    [c.navigationItem setRightBarButtonItem:r animated:NO];


[super pushViewController:n animated:NO];

 }

私がコードで言及したように、私は常に左のボタンの項目を持っているので、アニメーションデリゲートのコンテキストとして渡す配列に配置する前にそれがnilかどうかをチェックしません。 これを行う場合は、そのチェックをしたいかもしれません。

私が見つけた問題は、デリゲートメソッドでクラッシュすると、プログラムがクラッシュしないということでした。 デリゲートが完了するのを止めるだけですが、警告は表示されません。
そのデリゲートルーチンで私のクリーンアップを行っていたので、それはクリーンアップを終了していないので、奇妙な視覚的な振る舞いを引き起こしていました。

私が作成する戻るボタンは "goBack"メソッドを呼び出し、そのメソッドは単にpopルーチンを呼び出します。

-(void)goBack
{ 
     [self popViewControllerAnimated:YES];
}

また、ここに私のポップのルーチンです。

-(UIViewController *)popViewControllerAnimated:(BOOL)animated
{
    //get the count for the number of viewControllers on the stack
int viewCount = [[self viewControllers] count];
//get the top view controller on the stack
UIViewController *topViewController = [self.viewControllers objectAtIndex:viewCount - 1];
//get the next viewController after the top one (this will be the new top one)
UIViewController *newTopViewController = [self.viewControllers objectAtIndex:viewCount - 2];

//if no animation was requested, we can skip the cross fade
if(!animated)
{
    [super popViewControllerAnimated:NO];
            return topViewController;
}



//start of the cross fade pop.  A bit tricky.  We need to add the new top controller
//as a subview of the curent view controler with an alpha of 0.  We then do a cross fade.
//After that we pop the view controller off the stack without animating it.
//Then the cleanup happens: if the view that was popped is not released, then we
//need to remove the subview we added and change some titles back.
newTopViewController.view.alpha = 0.0;
[topViewController.view addSubview:newTopViewController.view];
[topViewController.view bringSubviewToFront:newTopViewController.view];
NSString *title = [topViewController.title retain];
UIBarButtonItem *lButtonItem = topViewController.navigationItem.leftBarButtonItem;
UIBarButtonItem *rButtonItem = topViewController.navigationItem.rightBarButtonItem;

//set the new buttons on top of the current controller from the new top controller
if(newTopViewController.navigationItem.leftBarButtonItem != nil)
{
    [topViewController.navigationItem setLeftBarButtonItem:newTopViewController.navigationItem.leftBarButtonItem animated:YES];
}
if(newTopViewController.navigationItem.rightBarButtonItem != nil)
{
    [topViewController.navigationItem setRightBarButtonItem:newTopViewController.navigationItem.rightBarButtonItem animated:YES];
}

[topViewController setTitle:newTopViewController.title];
//[topViewController.navigationItem.leftBarButtonItem setTitle:newTopViewController.navigationItem.leftBarButtonItem.title];

NSArray *array = nil;
if(rButtonItem != nil)
    array = [[NSArray alloc] initWithObjects:topViewController,title,lButtonItem,rButtonItem,nil];
else {
    array = [[NSArray alloc] initWithObjects:topViewController,title,lButtonItem,nil];
}


[UIView beginAnimations:@"pop view" context:array];
[UIView setAnimationDidStopSelector:@selector(animationForCrossFadePopDidStop:finished:context:)];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.80];
[newTopViewController.view setAlpha: 1.0];
[UIView commitAnimations];
return topViewController;

 }

 -(void)animationForCrossFadePopDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
 {

UIViewController *c = [(NSArray *)context objectAtIndex:0];
//UIViewController *n = [(NSArray *)context objectAtIndex:1];
NSString *title = [(NSArray *)context objectAtIndex:1];
UIBarButtonItem *l = [(NSArray *)context objectAtIndex:2];
UIBarButtonItem *r = nil;



//Not all views have a right bar button.  If we look for one that isn't there
// we'll crash out and not complete this method, but the program will continue.
//So we need to check if it is therea nd skip it if it isn't.
if([(NSArray *)context count] == 4)
    r = [(NSArray *)context objectAtIndex:3];

//pop the current view from the stack without animation
[super popViewControllerAnimated:NO];

//if what was the current veiw controller is not nil, then lets correct the changes
//we made to it.
if(c != nil)
{
    //remove the subview we added for the transition
    [[c.view.subviews lastObject] removeFromSuperview];
    //reset the title we changed
    c.title = title;
    [title release];
    //replace the left bar button that we changed
    [c.navigationItem setLeftBarButtonItem:l animated:NO];
    //if we were passed a right bar button item, replace that one as well
    if(r != nil)
        [c.navigationItem setRightBarButtonItem:r animated:NO];
    else {
        [c.navigationItem setRightBarButtonItem:nil animated:NO];
    }


 }
}

それはかなりです。 ローテーションを実装する場合は、いくつかの追加コードが必要になります。 表示する前にサブビューとして追加するビューのフレームサイズを設定する必要があります。そうしないと、方向が横向きですが、直前のビューを見たのはそのポートレイトです。 それで、それをサブビューとして追加してフェードインしますが、それはポートレートとして表示されます。アニメーションなしでポップすると、同じビューがスタックにあるものが現在は横長です。 全体がちょっとファンキーに見えます。 誰もがローテーションを実装しているのは少し違っているので、ここに私のコードは含めていません。

それが人々に役立つことを願っています。 私はこのようなことを何度も見てきて何も見つけられませんでした。 I don't think this is the perfect answer, but it is working real well for me at this point.




Using iJordan's answer as inspiration, why not simply create a Category on UINavigationController to use throughout your app instead of copying/pasting this animation code all over the place?

UINavigationController+Animation.h

@interface UINavigationController (Animation)

- (void) pushViewControllerWithFlip:(UIViewController*) controller;

- (void) popViewControllerWithFlip;

@end

UINavigationController+Animation.m

@implementation UINavigationController (Animation)

- (void) pushViewControllerWithFlip:(UIViewController *) controller
{
    [UIView animateWithDuration:0.50
                     animations:^{
                         [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                         [self pushViewController:controller animated:NO];
                         [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:NO];
                     }];
}

- (void) popViewControllerWithFlip
{
    [UIView animateWithDuration:0.5
                     animations:^{
                         [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                         [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:NO];
                     }];

    [self popViewControllerAnimated:NO];
}

@end

Then simply import the UINavigationController+Animation.h file and call it normally:

[self.navigationController pushViewControllerWithFlip:[[NewViewController alloc] init]];

[self.navigationController popViewControllerWithFlip];



Links