1. 程式人生 > >ios導航欄的使用和滑動返回

ios導航欄的使用和滑動返回

 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...

3UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];

4self.navigationItem.leftBarButtonItem = barItem;   //not working

5self.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