Objective c CATTransition还可以设置导航栏的动画

Objective c CATTransition还可以设置导航栏的动画,objective-c,uiview,uinavigationcontroller,catransition,Objective C,Uiview,Uinavigationcontroller,Catransition,我想制作一个自定义动画来弹出我的导航控制器。我只想设置视图的动画,而不是导航栏。使用这段代码,我对视图和导航栏都设置了动画。我怎样才能只设置视图的动画 CATransition* transition = [CATransition animation]; transition.duration = 0.3; transition.type = kCATransitionFade; transition.subtype = kCATransitionFromTop; [self.navigat

我想制作一个自定义动画来弹出我的导航控制器。我只想设置视图的动画,而不是导航栏。使用这段代码,我对视图和导航栏都设置了动画。我怎样才能只设置视图的动画

CATransition* transition = [CATransition animation];
transition.duration = 0.3;
transition.type = kCATransitionFade;
transition.subtype = kCATransitionFromTop;

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

当按下navigationcontroller栏中添加的自定义后退按钮时,将触发此代码。

以下是一段代码,用于对后退按钮和调用
popRootViewController:
方法进行自定义动画

它是一个扩展了
UINavigationViewController
的类,它本身与苹果的文档相矛盾,它还使用KVO分配私有变量,一旦工程师更改
UINavigationController
类,它可能会停止工作,所以使用它的风险自负

#import "MyNavigationController.h"

@interface MyNavigationController () <UINavigationBarDelegate> {
    // Flag that we will use to avoid collisions between navgiation bar
    // when we call popViewControllerAnimated: method directly
    BOOL _isPopping;
}
- (UIViewController *)myPopViewControllerAniamted:(BOOL)animated;
@end

@implementation MyNavigationController

- (id)init
{
    self = [super init];
    if (!self) return nil;
    // We can't intercept delegation of the original navigation bar,
    // we have to replace it with our own, by assigning new instance to
    // the private _navigationBar vairable
    UINavigationBar *navigationBar = [[UINavigationBar alloc] init];
    navigationBar.delegate = self;
    [self setValue:navigationBar forKey:@"_navigationBar"];

    return self;
}

// This is the delegate method called when you're about to pop navigation item
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
{
// If we're in the process of popping items we don't want to reenter
    if (!_isPopping) {
        [self myPopViewControllerAniamted:YES];
    }
    return YES;
}

// Similarly we have to override popToRootViewControllerAnimated:
// The only difference would be that we use not previous view as a
// target for the transfition, but the very first view
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
    return [self myPopViewControllerAniamted:animated];
}

// Our custom popping method
- (UIViewController *)myPopViewControllerAniamted:(BOOL)animated
{
    _isPopping = YES;
    // If we got here, we have at least two view controllers in the stack
    UIViewController *currentViewController = self.topViewController;
    if (animated && self.viewControllers.count > 1) {
        UIView *currentView = currentViewController.view;
        UIViewController *previousViewController = [self.viewControllers objectAtIndex:self.viewControllers.count - 2];
        UIView *previousView = previousViewController.view;
        previousView.alpha = 0.0;
        [currentView.superview insertSubview:previousView belowSubview:currentView];
        // I use UIView just for the sake of the simplicity of this example
        // In case of core animation you will have to deal with delegates
        // to trigger view controller popping when animation finishes
        [UIView animateWithDuration:0.33 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            currentView.alpha = 0.0;
            previousView.alpha = 1.0;
        } completion:^(BOOL finished) {
            [super popViewControllerAnimated:NO];
            _isPopping = NO;
        }];
    } else {
        [super popViewControllerAnimated:NO];
        _isPopping = NO;
    }
    return currentViewController;
}

@end
#导入“MyNavigationController.h”
@接口MyNavigationController(){
//我们将用于避免导航条之间碰撞的标志
//当我们直接调用popViewControllerAnimated:方法时
布卢伊波普;
}
-(UIViewController*)MyPopViewController已设置:(BOOL)已设置动画;
@结束
@MyNavigationController的实现
-(id)init
{
self=[super init];
如果(!self)返回nil;
//我们无法拦截原始导航栏的授权,
//我们必须将其替换为我们自己的,方法是将新实例分配给
//私人导航栏是有价值的
UINavigationBar*导航栏=[[UINavigationBar alloc]init];
navigationBar.delegate=self;
[self-setValue:navigationBar-forKey:@“_navigationBar”];
回归自我;
}
//这是将要弹出导航项时调用的委托方法
-(BOOL)导航栏:(UINavigationBar*)导航栏应为选项:(UINavigationItem*)项
{
//如果我们正在弹出我们不想重新输入的项目
如果(!\u iSping){
[self MyPopViewControllerAnimated:是];
}
返回YES;
}
//同样,我们必须覆盖PoptorootViewController激活:
//唯一的区别是我们不使用前一个视图作为
//转换的目标,但是第一个视图
-(UIViewController*)PopViewController动画:(BOOL)动画
{
返回[self MyPopViewControllerAnimated:已设置动画];
}
//我们的自定义弹出方法
-(UIViewController*)MyPopViewController已设置:(BOOL)已设置动画
{
_ispop=是;
//如果我们到了这里,堆栈中至少有两个视图控制器
UIViewController*currentViewController=self.topViewController;
如果(动画和self.viewControllers.count>1){
UIView*currentView=currentViewController.view;
UIViewController*previousViewController=[self.viewControllers objectAtIndex:self.viewControllers.count-2];
UIView*previousView=previousViewController.view;
previousView.alpha=0.0;
[currentView.superview insertSubview:previousView低于SubView:currentView];
//我使用UIView只是为了简单起见
//对于核心动画,您必须处理代理
//动画完成时触发视图控制器弹出的步骤
[UIView animateWithDuration:0.33延迟:0.0选项:UIViewAnimationOptionCurveEaseInOut动画:^{
currentView.alpha=0.0;
previousView.alpha=1.0;
}完成:^(布尔完成){
[超级PopViewController激活:否];
_ispop=否;
}];
}否则{
[超级PopViewController激活:否];
_ispop=否;
}
返回电流控制器;
}
@结束
再一次,我强烈建议大家阅读《可能满足您的需求》一书,作为定制视图控制器行为的一种指定方式,它完全是作为一种可行的练习


希望有帮助

如果您能告诉我们上面的代码片段是在什么地方执行的,这将是非常有益的?(在选项卡栏的委托方法中?在另一个父视图控制器中?,…)您是否在viedDidLoad事件中调用上述代码?@NENAMINIMHAJLOVIC当触摸导航栏中的“我的默认后退”按钮时,会调用它