记录一下涉及导航控制器UINavigationController的一些使用方法。
一、把控制器嵌套进导航栏:
ViewController *viewController = [[ViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
二、在当前控制器改变导航栏的背景颜色:
[self.navigationController.navigationBar setBarTintColor:[UIColor greenColor]];
三、定制导航栏字体:
[self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor], NSFontAttributeName: [UIFont boldSystemFontOfSize:20]}];
四、增加导航按钮并改变按钮字体颜色:
UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithTitle:@"确定" style:UIBarButtonItemStylePlain target:self action:@selector(onConfirm:)];
self.navigationItem.rightBarButtonItem = rightItem;
[self.navigationController.navigationBar setTintColor:[UIColor whiteColor]];
五、改变导航栏上状态条的颜色:
self.navigationController.navigationBar.barStyle = UIStatusBarStyleLightContent;
六、使用自定义的图片作为导航栏的背景:
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:[UIImage new]];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"nav"]];
[self.navigationController.navigationBar insertSubview:imageView atIndex:0];
可将以上代码中的imageView换成自定义的界面。
七、以上对导航栏的定制可以使用[UINavigationBar appearance]的设置使全局生效,例如:
[[UINavigationBar appearance] setBarTintColor:[UIColor greenColor]];
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
八、使导航栏和状态条跟随UITableView的滚动消失或显示:
[self.navigationController setHidesBarsOnSwipe:YES];
上面的代码不会使状态栏也跟随消失或显示,解决方法为监听导航栏隐藏或显示时的滑动手势,根据当前导航栏的显示状态来更新状态栏的状态:[self.navigationController.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipe:)];
- (BOOL)prefersStatusBarHidden {
return _hideStatusBar;
}
- (void)swipe:(UISwipeGestureRecognizer *)recognizer {
_hideStatusBar = self.navigationController.navigationBar.frame.origin.y < 0;
[UIView animateWithDuration:0.2 animations:^{
[self setNeedsStatusBarAppearanceUpdate];
}];
}
最终效果:
九、自定义导航栏的转场动画。
iOS7以上就可以实现导航栏的自定义转场效果了,实现UINavigationControllerDelegate和UIViewControllerAnimatedTransitioning协议即可。
隐藏当前UIViewController的导航栏,并放置一个UIImageView到界面上
self.navigationController.navigationBarHidden = YES;
_theImageView = [[UIImageView alloc] initWithFrame:self.view.frame];
[_theImageView setImage:[UIImage imageNamed:@"1.jpg"]];
[self.view addSubview:_theImageView];
声明一个成员变量,用于记录当前导航栏的操作是push还是pop
UINavigationControllerOperation _navOperation;
实现以下方法
#pragma mark - UINavigationControllerDelegate, UIViewControllerAnimatedTransitioning
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
_navOperation = operation;
return self;
}
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return 3;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
UIView *containerView = [transitionContext containerView];
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
if (_navOperation == UINavigationControllerOperationPush) {
[containerView insertSubview:toView atIndex:0];
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
fromView.transform = CGAffineTransformMakeScale(1.2, 1.2);
} completion:^(BOOL finished) {
fromView.transform = CGAffineTransformIdentity;
[transitionContext completeTransition:YES];
}];
}
}
上面第一个方法用于记录当前跳转的操作,第二个方法是动画的时间,第三个方法是动画的实现。这里要实现的效果是当执行push操作时,当前界面慢慢变大然后消失,露出需要跳转到界面。
指定导航栏的协议实现者为当前控制器
self.navigationController.delegate = self;
在当前界面显示完成后延时5秒执行跳转
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
SecondViewController *secondViewController = [[SecondViewController alloc] init];
[self.navigationController pushViewController:secondViewController animated:YES];
});
}
最终可以看到以下的效果: