![](https://img-my.csdn.net/uploads/201211/22/1353585415_6786.jpg)
A.有多个控件。
[self.navigationItemsetRightBarButtonItems:[NSArrayarrayWithObjects: rightButton, backBtn1,closeBtn1 ,nil]];
[self.navigationItem setLeftBarButtonItems:[NSArray arrayWithObjects: leftButton, backBtn,closeBtn ,nil]];
B.一两个控件
self.navigationItem.leftBarButtonItem
backBarButtonItem是返回按钮,这个不用多说,也可以自定义。
leftBarButtonItem如果设置,会替换掉backBarButtonItem,5.0以上可以设置leftItemsSupplementBackButton为yes,来同时显示left和back。一般 应用情况,比如rootViewController是不需要返回按钮的,可以用left在左侧加按钮。
UINavgationBar的backItem保存了topItem的下一个item,即索引为n-2的item。如果当前只有一个item,那么该属性为nil,而不是与topItem指向相同的item。
//self.navigationItem.title = @"这么任性好么";
UILabel *title = [[UILabelalloc]initWithFrame:self.view.bounds];
title.textColor = [UIColorwhiteColor];
title.backgroundColor = [UIColorclearColor];
title.textAlignment =NSTextAlignmentCenter;
title.text =@"产品库";
title.font = [UIFontfontWithName:@"Helvetica-Bold"size:20];
self.navigationItem.titleView = title;
[self.navigationController.navigationBarsetBarTintColor:[UIColorcolorWithRed:1green:0.1blue:0.1alpha:1.000]]; //设置导航栏背景颜色
3,滑动返回。
iOS 7中在传统的左上角返回键之外,提供了右滑返回上一级界面的手势。支持此手势的是UINavigationController中新增的属性
interactivePopGestureRecognizer,即右滑返回只支持以UINavigationController为容器的ViewController间切换,要想在自定义容 器中使用,需要一些额外的工作。
基本地,控制ViewController是否启用右滑返回,只需要这样:
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
默认情况下enabled为YES。
在实际使用中,遇到了一些问题,整理如下:
1、自定义返回按钮后,右滑返回失效;
解决方案:比较直观的办法是在自定义返回按钮时,使用backBarButtonItem:
1 UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
2 //some initialize code here...
3 UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
4 self.navigationItem.leftBarButtonItem = barItem; //not working
5 self.navigationItem.backBarButtonItem = barItem; //serve well
但这样无法支持左上角多个按钮的情况。考虑到 interactivePopGestureRecognizer也有delegate属性,替换默认的self . navigationController .interactivePopGestureRecognizer.delegate来配置右滑返回的表现也是可行的。在rootViewController中:
self.navigationController.interactivePopGestureRecognizer.delegate =self;
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if (self.navigationController.viewControllers.count ==1)//关闭主界面的右滑返回
{
returnNO;
}
else {
return YES;
}
}
这种方式没有办法自定义转场动画,下面的是可以自定义转场动画的方式。
// UINavigationController.h
@property(nullable,nonatomic,weak)id<UINavigationControllerDelegate> delegate;
要使用这个代理。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_revenueAnalyseVc = [[layerViewController alloc] init];
UINavigationController *rootNavigationController = [[UINavigationController alloc] initWithRootViewController:_revenueAnalyseVc];
[rootNavigationController setNavigationBarHidden:YES];
rootNavigationController.delegate = [NavigationPerformer getNavigationPerformerInstance];
[[NavigationPerformer getNavigationPerformerInstance] setupPanGesture:rootNavigationController];
self.window.rootViewController = rootNavigationController;
[self.window makeKeyAndVisible];
return YES;
}
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface NavigationPerformer : NSObject <UINavigationControllerDelegate>
@property (nonatomic, strong) id<UIViewControllerAnimatedTransitioning> pushAnimation;
@property (nonatomic, strong) id<UIViewControllerAnimatedTransitioning> popAnimation;
@property (nonatomic, weak) UINavigationController *referenceNaviController;
@property (nonatomic, strong) UIPercentDrivenInteractiveTransition *interactionController;
@property (nonatomic, assign) CGPoint locationS;
+(NavigationPerformer *)getNavigationPerformerInstance;
-(void)setupPanGesture: (UINavigationController *)referenceNaviController;
@property (nonatomic, assign) BOOL isInMoveState;
@end
#import "NavigationPerformer.h"
#import "transAnimate.h"
@implementation NavigationPerformer
- (id)init{
if (self = [super init]) {
_pushAnimation = [[transAnimate alloc] init];
((transAnimate*)_pushAnimation).theType = animateTypePush;
_popAnimation = [[transAnimate alloc] init];
((transAnimate*)_popAnimation).theType = animateTypePop;
}
return self;
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC
{
if (operation == UINavigationControllerOperationPush) {
return self.pushAnimation;
}
else if (operation == UINavigationControllerOperationPop) {
return self.popAnimation;
}
return nil;
}
- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController {
return self.interactionController;
}
+(NavigationPerformer *)getNavigationPerformerInstance {
static dispatch_once_t once;
static NavigationPerformer * NavigationPerformerInstance;
dispatch_once(&once, ^{
NavigationPerformerInstance = [[NavigationPerformer alloc] init];
});
return NavigationPerformerInstance;
}
- (void)pan:(UIPanGestureRecognizer *)pan {
UIView *view = self.referenceNaviController.view;
if (pan.state == UIGestureRecognizerStateBegan) {
_locationS = [pan translationInView:view];
}
else if (pan.state == UIGestureRecognizerStateChanged) {
CGPoint translation = [pan translationInView:view];
if (translation.x - _locationS.x > 0 && self.referenceNaviController.viewControllers.count > 1) {
if (!_isInMoveState) {
_isInMoveState = YES;
self.interactionController = [[UIPercentDrivenInteractiveTransition alloc] init];
[self.referenceNaviController popViewControllerAnimated:YES];
}
}
CGFloat progress = (translation.x - _locationS.x) / [UIScreen mainScreen].bounds.size.width;
[self.interactionController updateInteractiveTransition:progress];
}
else if (pan.state == UIGestureRecognizerStateEnded) {
CGPoint translation = [pan translationInView:view];
if(translation.x - _locationS.x > 20) {
[self.interactionController finishInteractiveTransition];
}
else {
[self.interactionController cancelInteractiveTransition];
}
_isInMoveState = NO;
_locationS = CGPointZero;
self.interactionController = nil;
}
}
-(void)setupPanGesture: (UINavigationController *)referenceNaviController {
self.referenceNaviController = referenceNaviController;
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
[self.referenceNaviController.view addGestureRecognizer:panGesture];
}
@end
下面的代码是push或是pop的动画自定义。
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
typedef enum {
animateTypePush,
animateTypePop
}animateType;
@interface transAnimate : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic, assign) animateType theType;
@end
#import "transAnimate.h"
@implementation transAnimate
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext {
return 2.5;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
UIViewController *desController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController *srcController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
CGRect shadowStartFrame, shadowEndFrame;
CGRect srcViewRectTo;
CGRect desViewRectTo;
CGRect srcViewRectFrom;
CGRect desViewRectFrom;
UIView *maskView = nil;
CGFloat maskAlphaend = 0.0;
UIImageView *shadowImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"trans_shadow"]];
if (_theType == animateTypePush) {
[[transitionContext containerView] addSubview:desController.view];
srcViewRectTo = CGRectMake(-[UIScreen mainScreen].bounds.size.width/2, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
desViewRectTo = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
srcViewRectFrom = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
desViewRectFrom = CGRectMake([UIScreen mainScreen].bounds.size.width, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
}
else if (_theType == animateTypePop) {
[[transitionContext containerView] insertSubview:desController.view belowSubview:srcController.view];
srcViewRectTo = CGRectMake([UIScreen mainScreen].bounds.size.width, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
desViewRectTo = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
srcViewRectFrom = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
desViewRectFrom = CGRectMake(-[UIScreen mainScreen].bounds.size.width/2, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
maskView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
maskView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5f];
maskView.frame = desViewRectFrom;
maskView.alpha = 0.3;
[[transitionContext containerView] insertSubview:maskView belowSubview:srcController.view];
shadowStartFrame = CGRectMake(srcViewRectFrom.origin.x - 8, srcViewRectFrom.origin.y, 8, srcViewRectFrom.size.height);
shadowEndFrame = CGRectMake(srcViewRectTo.origin.x - 8, srcViewRectTo.origin.y, 8, srcViewRectTo.size.height);
[[transitionContext containerView] insertSubview:shadowImageView aboveSubview:maskView];
}
desController.view.frame = desViewRectFrom;
srcController.view.frame = srcViewRectFrom;
shadowImageView.frame = shadowStartFrame;
[UIView animateWithDuration:[self transitionDuration:transitionContext]
delay:0
options:UIViewAnimationOptionCurveLinear
animations:^{
desController.view.frame = desViewRectTo;
srcController.view.frame = srcViewRectTo;
shadowImageView.frame = shadowEndFrame;
maskView.frame = desViewRectTo;
maskView.alpha = maskAlphaend;
}
completion:^(BOOL finished) {
[shadowImageView removeFromSuperview];
[maskView removeFromSuperview];
//srcController.view.transform = CGAffineTransformIdentity;
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end