导航栏相关点

作者: Kevin_wzx | 来源:发表于2017-10-13 12:00 被阅读60次

1.导航栏渐变

1.方法一(推荐)

封装的代码如下:
MXNavigationBarManager.h

//
//  MXNavigationBarManager.h
//  MXBarManagerDemo
//
//  Created by apple on 16/5/25.
//  Copyright © 2016年 desn. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface MXNavigationBarManager : NSObject

@property (nonatomic, strong) UIColor *barColor; //NavigationBar background color, default is white
@property (nonatomic, strong) UIColor *tintColor; //NavigationBar subviews color
@property (nonatomic, strong) UIImage *backgroundImage; //default is nil
@property (nonatomic, assign) UIStatusBarStyle statusBarStyle; // default is UIStatusBarStyleDefault

@property (nonatomic, assign) float zeroAlphaOffset;//color will changed begin this offset, default is -64
@property (nonatomic, assign) float fullAlphaOffset;//color alpha will be 1 in this offset, default is 200
@property (nonatomic, assign) float minAlphaValue;//bar minAlpha, default is 0
@property (nonatomic, assign) float maxAlphaValue;//bar maxAlpha, default is 1

@property (nonatomic, strong) UIColor *fullAlphaTintColor;//if you set this property, the tintColor will changed in fullAlphaOffset
@property (nonatomic, assign) UIStatusBarStyle fullAlphaBarStyle;//if you set this property, the barStyle will changed in fullAlphaOffset

@property (nonatomic, assign) BOOL allChange;//if allchange = yes, the tintColor will changed with the barColor change, default is yes, if you only want to change barColor, set allChange = NO
@property (nonatomic, assign) BOOL reversal;//this will cause that if currentAlpha = 0.3,it will be 1 - 0.3 = 0.7
@property (nonatomic, assign) BOOL continues;//when continues = YES, bar color will changed whenever you scroll, if you set continues = NO,it only be changed in the fullAlphaOffset


+ (void)setBarColor:(UIColor *)color;
+ (void)setTintColor:(UIColor *)color;
+ (void)setBackgroundImage:(UIImage *)image;
+ (void)setStatusBarStyle:(UIStatusBarStyle)style;

+ (void)setZeroAlphaOffset:(float)offset;
+ (void)setFullAlphaOffset:(float)offset;
+ (void)setMaxAlphaValue:(float)value;
+ (void)setMinAlphaValue:(float)value;

+ (void)setFullAlphaTintColor:(UIColor *)color;
+ (void)setFullAlphaBarStyle:(UIStatusBarStyle)style;

+ (void)setAllChange:(BOOL)allChange;
+ (void)setReversal:(BOOL)reversal;
+ (void)setContinues:(BOOL)continues;

+ (void)managerWithController:(UIViewController *)viewController;//you should use this method to init MXNavigationManager

+ (void)changeAlphaWithCurrentOffset:(CGFloat)currentOffset;// implemention this method in @selectot(scrollView: scrollViewDidScroll)

+ (void)reStoreToSystemNavigationBar; //change the navigationBar to system style

@end

MXNavigationBarManager.m

//
//  MXNavigationBarManager.m
//  MXBarManagerDemo
//
//  Created by apple on 16/5/25.
//  Copyright © 2016年 desn. All rights reserved.
//

#import "MXNavigationBarManager.h"

static const CGFloat kNavigationBarHeight  = 64.0f;
static const CGFloat kDefaultFullOffset    = 200.0f;
static const float   kMaxAlphaValue        = 0.995f;
static const float   kMinAlphaValue        = 0.0f;
static const float   kDefaultAnimationTime = 0.35f;

#define SCREEN_RECT [UIScreen mainScreen].bounds
#define BACKGROUNDVIEW_FRAME CGRectMake(0, -20, CGRectGetWidth(SCREEN_RECT), kNavigationBarHeight)

@interface MXNavigationBarManager ()

@property (nonatomic, strong) UINavigationBar *selfNavigationBar;
@property (nonatomic, strong) UINavigationController *selfNavigationController;

@property (nonatomic, strong) UIImage *saveImage;
@property (nonatomic, strong) UIColor *saveColor;
@property (nonatomic, strong) UIColor *saveTintColor;
@property (nonatomic, strong) NSDictionary *saveTitleAttribute;
@property (nonatomic, assign) UIStatusBarStyle saveBarStyle;

@property (nonatomic, assign) BOOL setFull;
@property (nonatomic, assign) BOOL setZero;
@property (nonatomic, assign) BOOL setChange;

@end

@implementation MXNavigationBarManager

#pragma mark - property set
+ (void)setBarColor:(UIColor *)color {
    [self sharedManager].barColor = color;
}

+ (void)setTintColor:(UIColor *)color {
    [self sharedManager].tintColor = color;
    [self sharedManager].selfNavigationBar.tintColor = color;
    [self setTitleColorWithColor:color];
}

+ (void)setBackgroundImage:(UIImage *)image {
    [[self sharedManager].selfNavigationBar setBackgroundImage:image
                                                 forBarMetrics:UIBarMetricsDefault];
}

+ (void)setStatusBarStyle:(UIStatusBarStyle)style {
    [self sharedManager].statusBarStyle = style;
    [[UIApplication sharedApplication] setStatusBarStyle:style];
}

+ (void)setZeroAlphaOffset:(float)offset {
    [self sharedManager].zeroAlphaOffset = offset;
}

+ (void)setFullAlphaOffset:(float)offset {
    [self sharedManager].fullAlphaOffset = offset;
}

+ (void)setMinAlphaValue:(float)value {
    value = value < kMinAlphaValue ? kMinAlphaValue : value;
    [self sharedManager].minAlphaValue = value;
}

+ (void)setMaxAlphaValue:(float)value {
    value = value > kMaxAlphaValue ? kMaxAlphaValue : value;
    [self sharedManager].maxAlphaValue = value;
}

+ (void)setFullAlphaTintColor:(UIColor *)color {
    [self sharedManager].fullAlphaTintColor = color;
}

+ (void)setFullAlphaBarStyle:(UIStatusBarStyle)style {
    [self sharedManager].fullAlphaBarStyle = style;
}

+ (void)setAllChange:(BOOL)allChange {
    [self sharedManager].allChange = allChange;
}

+ (void)setReversal:(BOOL)reversal {
    [self sharedManager].reversal = reversal;
}

+ (void)setContinues:(BOOL)continues {
    [self sharedManager].continues = continues;
}

+ (void)reStoreToSystemNavigationBar {
    [[self sharedManager].selfNavigationController setValue:[UINavigationBar new] forKey:@"navigationBar"];
}

#pragma mark - Public Method
+ (void)managerWithController:(UIViewController *)viewController {
    UINavigationBar *navigationBar = viewController.navigationController.navigationBar;
    [self sharedManager].selfNavigationController = viewController.navigationController;
    [self sharedManager].selfNavigationBar = navigationBar;
    [navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
    [navigationBar setShadowImage:[UIImage new]];
}

+ (void)changeAlphaWithCurrentOffset:(CGFloat)currentOffset {
    MXNavigationBarManager *manager = [self sharedManager];
    
    float currentAlpha = [self curretAlphaForOffset:currentOffset];
    
    if (![manager.barColor isEqual:[UIColor clearColor]]) {
        if (!manager.continues) {
            if (currentAlpha == manager.minAlphaValue) {
                [self setNavigationBarColorWithAlpha:manager.minAlphaValue];
            } else if (currentAlpha == manager.maxAlphaValue) {
                [UIView animateWithDuration:kDefaultAnimationTime animations:^{
                    [self setNavigationBarColorWithAlpha:manager.maxAlphaValue];
                }];
                manager.setChange = YES;
            } else {
                if (manager.setChange) {
                    [UIView animateWithDuration:kDefaultAnimationTime animations:^{
                        [self setNavigationBarColorWithAlpha:manager.minAlphaValue];
                    }];
                    manager.setChange = NO;
                }
            }
        } else {
            [self setNavigationBarColorWithAlpha:currentAlpha];
        }
    }
    
    if (manager.allChange) [self changeTintColorWithOffset:currentAlpha];
}


#pragma mark - calculation
+ (float)curretAlphaForOffset:(CGFloat)offset {
    MXNavigationBarManager *manager = [self sharedManager];
    float currentAlpha = (offset - manager.zeroAlphaOffset) / (float)(manager.fullAlphaOffset - manager.zeroAlphaOffset);
    currentAlpha = currentAlpha < manager.minAlphaValue ? manager.minAlphaValue : (currentAlpha > manager.maxAlphaValue ? manager.maxAlphaValue : currentAlpha);
    currentAlpha = manager.reversal ? manager.maxAlphaValue + manager.minAlphaValue - currentAlpha : currentAlpha;
    return currentAlpha;
}

+ (void)changeTintColorWithOffset:(float)currentAlpha {
    MXNavigationBarManager *manager = [self sharedManager];
    if (currentAlpha >= manager.maxAlphaValue && manager.fullAlphaTintColor != nil) {
        if (manager.setFull) {
            manager.setFull = NO;
            manager.setZero  = YES;
        } else {
            if (manager.reversal) {
                manager.setFull = YES;
            }
            return;
        }
        manager.selfNavigationBar.tintColor = manager.fullAlphaTintColor;
        [self setTitleColorWithColor:manager.fullAlphaTintColor];
        [self setUIStatusBarStyle:manager.fullAlphaBarStyle];
    } else if (manager.tintColor != nil) {
        if (manager.setZero) {
            manager.setZero = NO;
            manager.setFull = YES;
        } else {
            return;
        }
        manager.selfNavigationBar.tintColor = manager.tintColor;
        [self setTitleColorWithColor:manager.tintColor];
        [self setUIStatusBarStyle:manager.statusBarStyle];
    }
}

#pragma mark - private method
+ (MXNavigationBarManager *)sharedManager {
    static MXNavigationBarManager *manager;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[MXNavigationBarManager alloc] init];
        [self initBaseData:manager];
    });
    return manager;
}

+ (void)initBaseData:(MXNavigationBarManager *)manager {
    manager.maxAlphaValue = kMaxAlphaValue;
    manager.minAlphaValue = kMinAlphaValue;
    manager.fullAlphaOffset = kDefaultFullOffset;
    manager.zeroAlphaOffset = -kNavigationBarHeight;
    manager.setZero = YES;
    manager.setFull = YES;
    manager.allChange = YES;
    manager.continues = YES;
}

+ (void)setTitleColorWithColor:(UIColor *)color {
    NSMutableDictionary *textAttr = [NSMutableDictionary dictionaryWithDictionary:[self sharedManager].selfNavigationBar.titleTextAttributes];
    [textAttr setObject:color forKey:NSForegroundColorAttributeName];
    [self sharedManager].selfNavigationBar.titleTextAttributes = textAttr;
}

+ (void)setNavigationBarColorWithAlpha:(float)alpha {
    MXNavigationBarManager *manager = [self sharedManager];
    NSLog(@"alpha = %f", alpha);
    [self setBackgroundImage:[self imageWithColor:[manager.barColor colorWithAlphaComponent:alpha]]];
}

+ (void)setUIStatusBarStyle:(UIStatusBarStyle)style {
    [[UIApplication sharedApplication] setStatusBarStyle:style];
}

+ (UIImage *)imageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0, 0, 1, 1);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [color setFill];
    CGContextFillRect(context, rect);
    UIImage *imgae = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return imgae;
}

@end

控制器中调用如下图:
导入头文件、代理等步骤省略...

屏幕快照 2017-02-09 下午3.09.30.png 屏幕快照 2017-02-09 下午3.09.23.png

2.方法二

UINavigationBar+NavAlpha.h

//
//  UINavigationBar+NavAlpha.h
//  QiongTreval
//
//  Created by mac on 16/7/13.
//  Copyright © 2016年 QCQ. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface UINavigationBar (NavAlpha)
- (void)cnSetBackgroundColor:(UIColor *)backgroundColor;
- (void)cnReset;
@end

UINavigationBar+NavAlpha.m

//
//  UINavigationBar+NavAlpha.m
//  QiongTreval
//
//  Created by mac on 16/7/13.
//  Copyright © 2016年 QCQ. All rights reserved.
//

#import "UINavigationBar+NavAlpha.h"

@implementation UINavigationBar (NavAlpha)
static char alView;

-(void)setAlphaView:(UIView *)alphaView
{
    objc_setAssociatedObject(self, &alView, alphaView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(UIView *)alphaView
{
    return  objc_getAssociatedObject(self, &alView);
    
}

 //设置渐变
- (void)cnSetBackgroundColor:(UIColor *)backgroundColor
{

    if (!self.alphaView) {
        [self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
        self.alphaView = [[UIView alloc] initWithFrame:CGRectMake(0, -20, [UIScreen mainScreen].bounds.size.width, CGRectGetHeight(self.bounds) + 20)];
        self.alphaView.userInteractionEnabled = NO;
        self.alphaView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
        [self insertSubview:self.alphaView atIndex:0];
    }
    
    self.alphaView.backgroundColor = backgroundColor;
    
}

- (void)cnReset
{
    [self setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
    [self setShadowImage:nil];
    [self.alphaView removeFromSuperview];
    self.alphaView = nil;
}

@end

控制器中调用:

屏幕快照 2017-02-23 下午5.27.39.png 屏幕快照 2017-02-23 下午5.27.15.png

2.导航栏下划线

2.1 隐藏下划线

方法1:此方法下,在手势滑动返回时有点问题
self.navigationController.navigationBar.clipsToBounds = YES;???该方法是干嘛的?不用导航栏时….?

方法2:此方法推荐
@property (nonatomic, strong) UIView *navLineView;
- (void)viewWillAppear:(BOOL)animated {
    
    [super viewWillAppear:animated];
    _navLineView.hidden = YES;
}
- (void)viewDidDisappear:(BOOL)animated {
    
    [super viewDidDisappear:animated];
    _navLineView.hidden = NO;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    UIView *backgroundView = [self.navigationController.navigationBar subviews].firstObject;
    _navLineView = backgroundView.subviews.lastObject;
}

方法3(单页面设置)

屏幕快照 2017-10-26 上午11.34.22.png

方法4(全局设置)

屏幕快照 2017-10-26 上午11.34.32.png

2.2 设置导航栏底部线条颜色的代码:

屏幕快照 2017-10-26 上午11.36.40.png

3.导航栏背景色和透明度的问题

加上这句代码即可解决:self.navigationController.navigationBar.translucent=NO;
相关链接🔗:http://www.jianshu.com/p/d0dbba7f3abc

4.iOS隐藏导航栏正确做法

以往我们隐藏导航栏都是这样做:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
   [self.navigationController setNavigationBarHidden:YES animated:YES];
}
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [self.navigationController setNavigationBarHidden:NO animated:YES];
}

但是往往这样 会遇到一些奇怪的 bug ,想来想去 我想到这样做可能要更好一点:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.navigationController.view sendSubviewToBack:self.navigationController.navigationBar];
}

-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [self.navigationController.view bringSubviewToFront:self.navigationController.navigationBar];
}

补充:iOS导航栏的正确隐藏方式(问题具体化)

20160717150053880.gif

问题描述:在项目中经常碰到首页顶部是无限轮播,需要靠最上面显示.有的设置导航栏为透明等一系列的方法,这个可以借助第三方.或者干脆简单粗暴的直接隐藏掉导航栏.可是push到下一个页面的时候是需要导航栏的,如何做了,这里给出两种方法.

  • 第一种做法
    -注意这里一定要用动画的方式隐藏导航栏,这样在使用滑动返回手势的时候效果最好,和上面动图一致.这样做有一个缺点就是在切换tabBar的时候有一个导航栏向上消失的动画.
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [self.navigationController setNavigationBarHidden:YES animated:YES];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    [self.navigationController setNavigationBarHidden:NO animated:YES];
}
  • 第二种做法
    -设置self为导航控制器的代理,实现代理方法,在将要显示控制器中设置导航栏隐藏和显示,使用这种方式不仅完美切合滑动返回手势,同时也解决了切换tabBar的时候,导航栏动态隐藏的问题.
@interface WLHomePageController () <UINavigationControllerDelegate>

@end

@implementation WLHomePageController 

#pragma mark - lifeCycle
- (void)viewDidLoad {
    [super viewDidLoad];

    // 设置导航控制器的代理为self
    self.navigationController.delegate = self;
}

#pragma mark - UINavigationControllerDelegate
// 将要显示控制器
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    // 判断要显示的控制器是否是自己
    BOOL isShowHomePage = [viewController isKindOfClass:[self class]];

    [self.navigationController setNavigationBarHidden:isShowHomePage animated:YES];
}

5.修复navigationController侧滑关闭失效的问题

self.navigationController.interactivePopGestureRecognizer.delegate = (id)self

6.隐藏返回按钮后面的文字

[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];                                                

7.状态栏statusBar的背景颜色

相关链接🔗:http://www.jianshu.com/p/5c09c2700038

8.导航栏基础使用总结

相关链接🔗:http://www.jianshu.com/p/f0d3df54baa6

相关文章

网友评论

    本文标题:导航栏相关点

    本文链接:https://www.haomeiwen.com/subject/tlkzyxtx.html