一种UINavigationBar的简单封装

版本记录

版本号 时间
V1.0 2017.08.04

前言

  我们的app一般都需要导航栏,极个别的除外,比如说很多游戏是没有导航栏的,但是绝大部分是都有的,不同的app都有自己特点的导航栏,有的是透明的,有的是某种颜色的,等等。总之,我们做app不可避免的会碰到自定义导航栏的情况。这一个小框架主要就是对自定义导航栏进行了封装,提供了几种样式,希望对大家有所帮助。

框架了解

  这个小框架主要就是实现了自定义导航栏的功能,并提供了四种样式,有需要的可以直接把这个拖过去,如果有你需要的样式直接调用就可以了,如果没有只需要加一个枚举成员,在实现以下类似功能就可以了,希望能给您提供帮助。


框架实现

下面我们就直接看代码,看框架是如何实现的。

1. UINavigationBar+JJNavigationBar.h
#import 

extern NSString *const kJJNavigationBarDefaultTitleColor;
extern NSString *const kJJNavigationBarStyle4Color;

typedef NS_ENUM(NSInteger, JJUINavigationBarStyle) {
    JJUINavigationBarStyleDefault = 0,     // 白色背景, 带底部线
    JJUINavigationBarStyleValue1,          // 白色背景
    JJUINavigationBarStyleValue2,          // 透明背景, title灰色
    JJUINavigationBarStyleValue3,          // 透明背景, title白色
    JJUINavigationBarStyleValue4,          // 灰色背景
};

@interface UINavigationBar (JJNavigationBar)

@property (nonatomic, assign, readonly) JJUINavigationBarStyle jjStyle;
@property (nonatomic, strong, readonly) UIView *jjViewBottomLine;

+ (void)jjSetDefaultSytle;

- (void)jjSetNavigationBarStyle:(JJUINavigationBarStyle)style;

- (void)jjSetBackgroundImageWithColor:(UIColor *)backgroundColor alpha:(float)alpha;

@end
2. UINavigationBar+JJNavigationBar.m
#import "UINavigationBar+JJNavigationBar.h"
#import 

#define kJJNavigationBarFontSize   [UIFont systemFontOfSize:20.0]
#define kDefaultColor              ([UIColor whiteColor])

static char kJJNavigationBarBottomLineKey;
static char kJJNavigationBarStyleKey;

NSString *const kJJNavigationBarDefaultTitleColor = @"#3e3e3e";
NSString *const kJJNavigationBarStyle4Color = @"#f5f5f5";

@interface UINavigationBar ()

@property (nonatomic, assign) NSNumber *jjStyleObj;
@property (nonatomic, strong) UIView *jjViewBottomLine;

@end

@implementation UINavigationBar (JJNavigationBar)

#pragma mark - Get/Set Function

- (UIView *)jjViewBottomLine
{
    return objc_getAssociatedObject(self, &kJJNavigationBarBottomLineKey);
}

- (void)setJjViewBottomLine:(UIView *)newAldViewBottomLine
{
    objc_setAssociatedObject(self, &kJJNavigationBarBottomLineKey, newAldViewBottomLine, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSNumber *)jjStyleObj
{
    return objc_getAssociatedObject(self, &kJJNavigationBarStyleKey);
}

- (void)setJjStyleObj:(NSNumber *)newJjStyleObj
{
    objc_setAssociatedObject(self, &kJJNavigationBarStyleKey, newJjStyleObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (JJUINavigationBarStyle)aldStyle
{
    return self.jjStyleObj.intValue;
}

#pragma mark - Class Public Function

+ (void)jjSetDefaultSytle
{
    [UINavigationBar appearance].barTintColor = [UIColor whiteColor];
    [UINavigationBar appearance].barStyle = UIBarStyleDefault;
    [UINavigationBar appearance].translucent = NO;
    [UINavigationBar appearance].titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor whiteColor],
                                                         NSFontAttributeName:[UIFont boldSystemFontOfSize:18.5]};
    [UINavigationBar appearance].tintColor = [UIColor whiteColor];
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:16],NSFontAttributeName, nil];
    [[UIBarButtonItem appearance] setTitleTextAttributes:attributes forState:0];
}

#pragma mark - Object Private Function

- (void)jjRemoveBottom
{
    [self.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull objSub, NSUInteger idxSub, BOOL * _Nonnull stopSub) {
        if ([objSub isKindOfClass:NSClassFromString(@"_UIBarBackground")] ||
            [objSub isKindOfClass:NSClassFromString(@"_UINavigationBarBackground")]) {
            __block BOOL isFoundSystemBottomLine;
            [objSub.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull objSubBackground, NSUInteger idxSubBackground, BOOL * _Nonnull stopSubBackground) {
                if ([objSubBackground isKindOfClass:[UIImageView class]] &&
                    fabs(CGRectGetHeight(objSubBackground.bounds) - 1.0 / [UIScreen mainScreen].scale) < FLT_EPSILON) {
                    objSubBackground.hidden = YES;
                    isFoundSystemBottomLine = YES;
                    *stopSubBackground = YES;
                }
            }];
        }
    }];
}

- (void)jjSetupDefaultStyle
{
    if (!self.jjViewBottomLine) {
        [self jjRemoveBottom];
        
        self.jjViewBottomLine = [[UIView alloc] initWithFrame:CGRectMake(0.0, CGRectGetHeight(self.bounds) - 0.5, CGRectGetWidth(self.bounds), 0.5)];
        self.jjViewBottomLine.backgroundColor = [self jjColorWithHexString:@"e5e5e5" alpha:1.0];
        [self addSubview:self.jjViewBottomLine];
    }
    
    self.jjViewBottomLine.hidden = NO;
    self.titleTextAttributes = @{NSForegroundColorAttributeName:[self jjColorWithHexString:kJJNavigationBarDefaultTitleColor alpha:1.0],
                                 NSFontAttributeName:kJJNavigationBarFontSize};
    [self aldSetBackgroundImageWithColor:[UIColor whiteColor] alpha:1.0];
    self.translucent = NO;
}

- (void)jjSetupValue1
{
    [self jjRemoveBottom];
    self.jjViewBottomLine.hidden = YES;
    self.titleTextAttributes = @{NSForegroundColorAttributeName:[self jjColorWithHexString:kJJNavigationBarDefaultTitleColor alpha:1.0],
                                 NSFontAttributeName:kJJNavigationBarFontSize};
    [self aldSetBackgroundImageWithColor:[UIColor whiteColor] alpha:1.0];
    self.translucent = NO;
}

- (void)jjSetupValue2
{
    [self jjRemoveBottom];
    
    // 设置隐藏
    self.jjViewBottomLine.hidden = YES;
    self.titleTextAttributes = @{NSForegroundColorAttributeName:[self jjColorWithHexString:kJJNavigationBarDefaultTitleColor alpha:1.0],
                                 NSFontAttributeName:kJJNavigationBarFontSize};
    [self aldSetBackgroundImageWithColor:[UIColor clearColor] alpha:0.0];
    self.shadowImage = [UIImage new];
    self.translucent = YES;
}

- (void)jjSetupValue3
{
    [self jjRemoveBottom];
    
    // 设置隐藏
    self.jjViewBottomLine.hidden = YES;
    self.titleTextAttributes = @{NSForegroundColorAttributeName:[self jjColorWithHexString:@"#ffffff"  alpha:1.0],
                                 NSFontAttributeName:kJJNavigationBarFontSize};
    [self aldSetBackgroundImageWithColor:[UIColor clearColor] alpha:0.0];
    self.shadowImage = [UIImage new];
    self.translucent = YES;
}

- (void)jjSetupValue4
{
    [self jjRemoveBottom];
    
    // 设置隐藏
    self.jjViewBottomLine.hidden = YES;
    self.titleTextAttributes = @{NSForegroundColorAttributeName:[self jjColorWithHexString:kJJNavigationBarDefaultTitleColor alpha:1.0],
                                 NSFontAttributeName:kJJNavigationBarFontSize};
    [self aldSetBackgroundImageWithColor:[self jjColorWithHexString:kJJNavigationBarStyle4Color alpha:1.0] alpha:1.0];
    self.translucent = NO;
}

//根据颜色返回相应颜色填充的图片

- (UIImage *)aldImageWithColor:(UIColor *)color
{
    CGRect rect = CGRectMake(0.0, 0.0, 1.0, 1.0);
    
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *imageColor = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return imageColor;
}

#pragma mark - Object Public Function

- (void)jjSetNavigationBarStyle:(JJUINavigationBarStyle)style
{
    self.jjStyleObj = [NSNumber numberWithInt:style];
    
    switch (style) {
        case JJUINavigationBarStyleDefault:
        {
            [self jjSetupDefaultStyle];
        }
            break;
            
        case JJUINavigationBarStyleValue1:
        {
            [self jjSetupValue1];
        }
            break;
            
        case JJUINavigationBarStyleValue2:
        {
            [self jjSetupValue2];
        }
            break;
            
        case JJUINavigationBarStyleValue3:
        {
            [self jjSetupValue3];
        }
            break;
            
        case JJUINavigationBarStyleValue4:
        {
            [self jjSetupValue4];
        }
            break;
            
        default:
        {
            [self jjSetupDefaultStyle];
        }
            break;
    }
}

- (void)aldSetBackgroundImageWithColor:(UIColor *)backgroundColor alpha:(float)alpha
{
    [self setBackgroundImage:[self aldImageWithColor:[backgroundColor colorWithAlphaComponent:alpha]] forBarMetrics:UIBarMetricsDefault];
}

#pragma mark - Class Public Function

/**
 *   该函数的功能就是根据给的十六进制数和透明度返回对应的颜色值
 *   @param stringToConvert :十六进制字符串
 *   @param alpha :透明度
 */
- (UIColor *)jjColorWithHexString:(NSString *)stringToConvert alpha:(CGFloat)alpha
{
    NSString *cString = [[stringToConvert stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
    
    if ([cString length] < 6) {
        return kDefaultColor;
    }
    
    if ([cString hasPrefix:@"#"]) {
        cString = [cString substringFromIndex:1];
    }
    
    if ([cString length] != 6) {
        return kDefaultColor;
    }
    
    NSRange range = NSMakeRange(0, 2);
    NSString *rString = [cString substringWithRange:range];
    
    range.location = 2;
    NSString *gString = [cString substringWithRange:range];
    
    range.location = 4;
    NSString *bString = [cString substringWithRange:range];
    
    unsigned int red = 0, green = 0, blue = 0;
    if ([[NSScanner scannerWithString:rString] scanHexInt:&red] &&
        [[NSScanner scannerWithString:gString] scanHexInt:&green] &&
        [[NSScanner scannerWithString:bString] scanHexInt:&blue]) {
        return [UIColor colorWithRed:((float)red / 255.0f)
                               green:((float)green / 255.0f)
                                blue:((float)blue / 255.0f)
                               alpha:alpha];
    }
    
    return kDefaultColor;
}

@end

上面就是所有的代码了。


框架验证

下面我们就调用一下,看一下这个框架的效果。

1. JJNavigationVC.m
#import "JJNavigationVC.h"
#import "UIBarButtonItem+JJBarButtonItem.h"
#import "UINavigationBar+JJNavigationBar.h"

@interface JJNavigationVC ()

@end

@implementation JJNavigationVC

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.title = @"无题";
    self.view.backgroundColor = [UIColor lightGrayColor];
    
    //左边item
    self.navigationItem.leftBarButtonItem = [UIBarButtonItem jjLeftItem:self
                                                               selector:@selector(backButtonDidClick)
                                                            imageNormal:[UIImage imageNamed:@"my_sezhi1"]
                                                      imageHightlighted:[UIImage imageNamed:@"my_sezhi1"]
                                                       titleColorNormal:[UIColor blueColor]
                                                 titleColorHightlighted:[UIColor redColor]
                                                                  title:@"返回"
                                             ];
    
    //右边的item
    self.navigationItem.rightBarButtonItem = [UIBarButtonItem jjRightItem:self
                                                                 selector:@selector(collectionButtonDidClick)
                                                              imageNormal:[UIImage imageNamed:@"my_shoucang1"]
                                                        imageHightlighted:[UIImage imageNamed:@"my_shoucang1"]
                                
                                                            imageDisabled:[UIImage imageNamed:@"my_shoucang1"]
                                                         titleColorNormal:[UIColor blueColor]
                                                   titleColorHightlighted:[UIColor redColor]
                                                       titleColorDisabled:[UIColor blackColor]
                                                                    title:@"收藏"
                                              ];
    
    //设置导航栏背景
    [self.navigationController.navigationBar jjSetNavigationBarStyle:JJUINavigationBarStyleValue2];
}

#pragma mark - Action && Notification

- (void)backButtonDidClick
{
    NSLog(@"返回按钮");
}

- (void)collectionButtonDidClick
{
    NSLog(@"收藏按钮");
}

@end

下面就给出几种导航栏样式的效果示意图。

一种UINavigationBar的简单封装_第1张图片
default
一种UINavigationBar的简单封装_第2张图片
value1
一种UINavigationBar的简单封装_第3张图片
value2
一种UINavigationBar的简单封装_第4张图片
value3

后记

希望能够对大家有所帮助,欢迎指正其中的不足,谢谢~~~

一种UINavigationBar的简单封装_第5张图片
院子

你可能感兴趣的:(一种UINavigationBar的简单封装)