0

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

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];

当按下导航控制器栏中添加的自定义后退按钮时,将触发此代码。

4

1 回答 1

1

popRootViewController:这是一个为后退按钮和调用方法时执行自定义动画的代码。

这是一个扩展的类,UINavigationViewController它本身与 Apple 的文档相矛盾,它还使用 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

再一次,它纯粹是作为可能的练习而完成的,我强烈建议阅读UIViewController 指南,也许Container View Controller可以满足您作为自定义视图控制器行为的指定方式的需求。

希望能帮助到你!

于 2012-08-20T07:50:09.823 回答