ios导航栏的使用和滑动返回

1.在纵向模式下导航栏默认为44像素高,在横向模式下为32像素高,导航栏提供了一个很少用的提示模式,该模式将高度扩展了30像素,在纵向模式下为XXX*74像素,在横向模式下为XXX*74像素。
要向导航栏添加提示,则设置self.navigationItem.prompt = @"................"。


2,导航栏的布局。

    A.有多个控件。

    [self.navigationItemsetRightBarButtonItems:[NSArrayarrayWithObjects: rightButton, backBtn1,closeBtn1 ,nil]];

    [self.navigationItem setLeftBarButtonItems:[NSArray arrayWithObjects: leftButton, backBtn,closeBtn ,nil]];

  B.一两个控件

  self.navigationItem.leftBarButtonItem

  self . navigationItem . backBarButtonItem

   backBarButtonItem是返回按钮,这个不用多说,也可以自定义。

    leftBarButtonItem如果设置,会替换掉backBarButtonItem,5.0以上可以设置leftItemsSupplementBackButton为yes,来同时显示left和back。一般     应用情况,比如rootViewController是不需要返回按钮的,可以用left在左侧加按钮。


  self . navigationController . navigationBar . backItem
  self.navigationController.navigationBar.topItem
  UINavgationBar的topItem指定了当前navgation bar显示的内容,topItem为栈顶元素,假如当前navgation bar维护了n个items,那么topItem的索引为n-1 ; 
    UINavgationBar的backItem保存了topItem的下一个item,即索引为n-2的item。如果当前只有一个item,那么该属性为nil,而不是与topItem指向相同的item。 

 C.titel的两种设置

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

 
  

    默认情况下enabledYES

    在实际使用中,遇到了一些问题,整理如下:

    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





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值