从右到左推动画会导致导航栏损坏

时间:2013-05-19 11:47:10

标签: ios objective-c cocoa-touch uinavigationcontroller

我正在使用UIRTLNavigationController.m对我的UINavigationController进行子类化以从右到左执行推送(不是正常行为)我在这个问题的底部添加了这些警告:

 nested push animation can result in corrupted navigation bar
 Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.

我对这些错误进行了研究,发现了一个阻止您接收这些错误的课程:https://github.com/Plasma/BufferedNavigationController

我已将BufferedNavigationController .h和.m添加到我的项目中,将BufferedNavigationController.h中的行更改为: @interface BufferedNavigationController:UIRTLNavigationController 并将BufferedNavigationController设置为IB中的UINavigationController自定义子类。

视图仍在从右向左移动,方法在BufferedNavigationController中调用,但我仍然得到有关嵌套和..导航栏子视图树的警告可能会被破坏..

任何帮助将不胜感激。

UIRTLNavigationController.m:

#import "UIRTLNavigationController.h"


@implementation UIRTLNavigationController

- (id)initWithRootViewController:(UIViewController *)rootViewController
{
        self = [super initWithRootViewController:rootViewController];
        if (!self)
                return nil;
        return self;
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
        NSLog(@"pushViewController");
        // Add the viewController and a fake controller without animation. Then pop the fake controller with animation.
        UIViewController *fakeController = [[[UIViewController alloc] init] autorelease];
        [super setViewControllers:[[self viewControllers] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:viewController, fakeController, nil]] animated:NO];
        [super popViewControllerAnimated:animated];
}

- (void)popViewControllerAnimatedStep2:(UIViewController *)viewController
{
        // Push the new top controller with animation
        [super pushViewController:viewController animated:YES];
        // Remove the view that should have been popped
        NSMutableArray *arr = [NSMutableArray arrayWithArray:[self viewControllers]];
        [arr removeObjectAtIndex:[[self viewControllers] count]-2];
        [super setViewControllers:[NSArray arrayWithArray:arr] animated:NO];
}

- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
        NSLog(@"popViewControllerAnimated");

        if (animated)
        {
                // Save the controller that should be on top after this pop operation
                UIViewController *newTopController = [[self viewControllers] objectAtIndex:[[self viewControllers] count]-2];
                // Remove it from the stack. Leave the view that should be popped on top
                NSMutableArray *arr = [NSMutableArray arrayWithArray:[self viewControllers]];
                [arr removeObjectAtIndex:[[self viewControllers] count]-2];
                [super setViewControllers:[NSArray arrayWithArray:arr] animated:NO];
                // Schedule the next step
                [self performSelector:@selector(popViewControllerAnimatedStep2:) withObject:newTopController afterDelay:0];
                return [arr objectAtIndex:[arr count]-1];
        }
        return [super popViewControllerAnimated:NO];
}

- (void)dealloc {
    [super dealloc];
}


@end

2 个答案:

答案 0 :(得分:0)

我不知道你是创建自定义UINavigationController只是为了执行自定义转换,如果你这样做,有一种更简单的方法。如下面的代码

-(void)makeMyCustomAnimation {
      YourDestinationViewController *destinationController = [YourDestinationViewController 
                                                             alloc] initWithNib.....];//add the missing code fot ini

  CATransition* transition = [CATransition animation];
  transition.duration = .25; //you can change this value to fit your needs
  transition.timingFunction = [CAMediaTimingFunction functionWithName: 
                                           kCAMediaTimingFunctionEaseInEaseOut]; 
                                           //kCAMediaTimingFunctionLinear
                                           //kCAMediaTimingFunctionEaseIn
                                           //kCAMediaTimingFunctionEaseOut
                                           //kCAMediaTimingFunctionEaseInEaseOut
                                           //kCAMediaTimingFunctionDefault

   transition.type = kCATransitionPush; //kCATransitionMoveIn;
                                     //kCATransitionPush,  
                                     //kCATransitionReveal
                                     //kCATransitionFade

   transition.subtype = kCATransitionFromRight; 
                       //kCATransitionFromLeft,
                       //kCATransitionFromRight 
                       //kCATransitionFromTop, 
                      //kCATransitionFromBottom

[self.navigationController.view.layer addAnimation:transition
                                                            forKey:kCATransition];

[self.navigationController pushViewController:destinationController animated:NO];

}

您可以通过更改subtype值来更改转换的方向。(我可能会设置错误的子类型值,我会继续混合它们)

此外,您可以使用相同的方法来pop - 视图控制器。我

如果你想使用segues,只需创建一个自定义segue并覆盖-(void)perform方法,通过添加前面的代码添加一些内容,就可以使用它,你必须得到{{1}的视图控制器}和[self sourceViewController];

答案 1 :(得分:-1)

对我来说,问题是一个接一个地推动控制器,这一个接一个地引起了几个过渡动画。这个链接帮助了我: https://github.com/Plasma/BufferedNavigationController/blob/master/BufferedNavigationController.m

我从这个堆栈溢出答案得到它:iOS: popViewController unexpected behavior