从右到左推送动画导致损坏的导航栏 [英] Right To Left Push animation results in corrupted navigation bar
问题描述
我正在子类化我的 UINavigationController
执行推从右到左(不正常的行为)与UIRTLNavigationController.m我已经添加在这个问题的底部,得到以下警告:
嵌套推送动画可能导致导航栏损坏
完成意外状态下的导航转换。导航栏子视图树可能会损坏。
我研究过这些错误,发现一个类阻止你接收它们: https://github.com/Plasma/BufferedNavigationController
我添加了BufferedNavigationController .h和.m到我的项目,将BufferedNavigationController.h中的行更改为:
@interface BufferedNavigationController:UIRTLNavigationController
并将BufferedNavigationController设置为我的 UINavigationController
在IB中的自定义子类。
视图仍然从右向左移动,方法在BufferedNavigationController内调用,但我仍然得到警告关于嵌套和..Navigation栏子视图树可能会损坏..
任何帮助将不胜感激。
UIRTLNavigationController.m :
#importUIRTLNavigationController.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);
//添加viewController和一个没有动画的假控制器。然后用动画弹出假控制器。
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
{
//使用动画推送新的顶级控制器
[super pushViewController: viewController animated:YES];
//删除应该被弹出的视图
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)
{
//保存在弹出操作之后应该在上面的控制器
UIViewController * newTopController = [[self viewControllers] objectAtIndex: [[self viewControllers] count] -2];
//从堆栈中删除它。留下应该弹出的视图
NSMutableArray * arr = [NSMutableArray arrayWithArray:[self viewControllers]];
[arr removeObjectAtIndex:[[self viewControllers] count] -2];
[super setViewControllers:[NSArray arrayWithArray:arr] animated:NO];
//计划下一步
[self performSelector:@selector(popViewControllerAnimatedStep2 :) withObject:newTopController afterDelay:0];
return [arr objectAtIndex:[arr count] -1];
}
return [super popViewControllerAnimated:NO];
}
- (void)dealloc {
[super dealloc];
}
@end
我不知道你是否创建自定义UINavigationController只是执行自定义转换,如果你这样做,有一个更简单的方法来做。如下代码
- (void)makeMyCustomAnimation {
YourDestinationViewController * destinationController = [YourDestinationViewController
alloc] initWithNib .....]; //添加缺少的代码fot ini
CATransition * transition = [CATransition animation];
transition.duration = .25; //你可以改变这个值来满足你的需要
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];
}
通过更改子类型
值(我可能设置了错误的子类型值,我保持混合)。
也可以对视图控制器使用相同的方法 pop
。我
如果你想使用segue,只需创建一个自定义segue并覆盖 - (void)perform
方法通过添加前面的代码与一些添加,你必须得到视图控制器与 [self sourceViewController];
和 [self destinationViewController ];
I'm subclassing my UINavigationController
to perform a push from right to left (not normal behavior) with UIRTLNavigationController.m I've added at the bottom of this question and get these warnings:
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.
I've researched about these errors and found a class that prevents you from receiving them: https://github.com/Plasma/BufferedNavigationController
I've added BufferedNavigationController .h and .m to my project, changed the line in BufferedNavigationController.h to:
@interface BufferedNavigationController : UIRTLNavigationController
and seted BufferedNavigationController to be my UINavigationController
custom subclass in the IB.
Views are still moving from right to left , methods are getting called inside BufferedNavigationController but I'm still get the warnings about nested and ..Navigation Bar subview tree might get corrupted..
Any help would be appreciated.
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
I don't know if you are creating the custom UINavigationController just to perform a custom transition, if you do, there is an easier way to do it. Like the following code
-(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];
}
You can change the direction of your transition by changing the subtype
value.(I might be set the wrong value of the subtype, I keep mixing them)
Also you can use the same approach for pop
-ing the view controller. I
And It can be used if you want to use segues, just create a custom segue and overrode the -(void)perform
method by adding the previous code with some additions, you have to get the view controllers with [self sourceViewController];
and [self destinationViewController];
这篇关于从右到左推送动画导致损坏的导航栏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!