轻量的顶部提示栏分类

.h 文件

//
//  NSString+LGFString.h
//  LGFOCTool
//
//  Created by apple on 2017/5/2.
//  Copyright © 2017年 来国锋. All rights reserved.
//

#import 
#import "LGFOCTool.h"

typedef NS_ENUM(NSUInteger, lgf_TopBarMessageMode) {
    lgf_Overlay,// //视图不下移 默认
    lgf_Resize,// 视图下移 (设置此项将取消手势隐藏 LGFTopMessageView 和 LGFTopMessageView 点击事件)
};

#pragma mark - 提示view style

@interface LGFTopMessageStyle : NSObject
+ (instancetype)na;
// 提示文本
@property (copy, nonatomic) NSString *lgf_Message;
// 文本最多显示行数
@property (assign, nonatomic) NSInteger lgf_LabelMaxLine;
// 文本字体
@property (strong, nonatomic) UIFont *lgf_MessageLabelFont;
// 文本颜色
@property (strong, nonatomic) UIColor *lgf_MessageTextColor;
// 图片
@property (strong, nonatomic) UIImage *lgf_MessageIcon;
// 图片宽度
@property (assign, nonatomic) CGFloat lgf_IconWidth;
// 图片与文本与边框间距
@property (assign, nonatomic) CGFloat lgf_BetweenIconAndMessage;
// 显示滞留时间 设置 0.0 为无限 
@property (assign, nonatomic) CGFloat lgf_DimissDelay;
// 动画时间
@property (assign, nonatomic) CGFloat lgf_AnimateDuration;
// TopBar中间 label 距离顶部和底部两边边距
@property (assign, nonatomic) CGFloat lgf_TopBarSpacingHeight;
// 背景颜色
@property (strong, nonatomic) UIColor *lgf_MessageBackColor;
// 视图是否下移
@property (assign, nonatomic) lgf_TopBarMessageMode lgf_MessageMode;
@end

#pragma mark - 提示view

@interface LGFTopMessageView : UIView
@property (strong, nonatomic) LGFTopMessageStyle *style;
@property (nonatomic, strong) UIImageView *messageIcon;
@property (nonatomic, strong) UILabel *messageLabel;
// 点击回调 Block
@property (nonatomic, copy) dispatch_block_t tapHandler;
lgf_AllocOnlyOnceForH(shard);
@end

#pragma mark - 提示view UIViewController 分类结合

@interface UIViewController (LGFTopBarMessage)

/**
 展示顶部警报条
 @param style        参数设置
 @param tapHandler   点击顶部条回调 lgf_TopBarMessageMode 为 lgf_Resize 该项无效
 */
- (void)lgf_ShowTopMessageWithStyle:(LGFTopMessageStyle *)style withTapBlock:(dispatch_block_t)tapHandler;

/**
 展示顶部提示条
 @param message      提示文字
 */
- (void)lgf_ShowTopMessage:(NSString *)message;

/**
 隐藏弹出视图
 */
- (void)lgf_DismissTopMessage;

@end


.m 文件

//
//  NSString+LGFString.m
//  LGFOCTool
//
//  Created by apple on 2017/5/2.
//  Copyright © 2017年 来国锋. All rights reserved.
//

#import "UIViewController+LGFTopBarMessage.h"
#import 

@implementation LGFTopMessageView

lgf_AllocOnlyOnceForM(LGFTopMessageView, shard);

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        self.messageLabel = [[UILabel alloc] init];
        self.messageLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        [self addSubview:self.messageLabel];
        self.messageIcon = [[UIImageView alloc] init];
        [self addSubview:self.messageIcon];
        
        // 添加轻扫手势
        UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismiss)];
        swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
        [self addGestureRecognizer:swipeUp];
        UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismiss)];
        swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
        [self addGestureRecognizer:swipeLeft];
        UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismiss)];
        swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
        [self addGestureRecognizer:swipeRight];
        
        // 添加轻击手势
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapNow)];
        [self addGestureRecognizer:tap];
    }
    return self;
}

- (void)tapNow {
    // 点击了message
    [self dismiss];
    if (self.tapHandler) {
        self.tapHandler();
    }
}

- (void)dismiss {
    // 隐藏 LGFTopMessageView
    [UIView animateWithDuration:self.style.lgf_AnimateDuration animations:^{
        self.superview.transform = CGAffineTransformIdentity;
        if (self.style.lgf_MessageMode == lgf_Overlay) {
            self.lgf_y -= (self.style.lgf_TopBarSpacingHeight + self.messageLabel.lgf_height);
        }
    } completion:^(BOOL finished) {
        [self removeFromSuperview];
    }];
}

- (void)setStyle:(LGFTopMessageStyle *)style {
    _style = style;
    [self resetViews];
}

- (void)resetViews {
    // 控件赋值
    self.messageLabel.numberOfLines = self.style.lgf_LabelMaxLine;
    self.messageLabel.text = self.style.lgf_Message;
    self.backgroundColor = self.style.lgf_MessageBackColor;
    self.messageLabel.textColor = self.style.lgf_MessageTextColor;
    self.messageIcon.image = self.style.lgf_MessageIcon;
    self.messageLabel.font = self.style.lgf_MessageLabelFont;
}

- (void)layoutSubviews {
    // 根据文字获取动态高度
    CGFloat labelWidth = self.lgf_width - (self.style.lgf_BetweenIconAndMessage * 3 + self.style.lgf_IconWidth);
    CGFloat labelHeight = MIN([self.style.lgf_Message lgf_HeightWithFont:self.style.lgf_MessageLabelFont constrainedToWidth:labelWidth], [@"" lgf_HeightWithFont:self.style.lgf_MessageLabelFont constrainedToWidth:labelWidth] * self.style.lgf_LabelMaxLine);
    if (!self.style.lgf_MessageIcon) {
        self.style.lgf_IconWidth = 0.0;
    }
    self.messageIcon.frame = CGRectMake(self.style.lgf_BetweenIconAndMessage, MAX(0, (self.lgf_height - self.style.lgf_IconWidth) / 2), self.style.lgf_IconWidth, self.style.lgf_IconWidth);
    self.messageLabel.frame = CGRectMake(self.style.lgf_IconWidth + self.style.lgf_BetweenIconAndMessage * 2, MAX(0, (self.lgf_height - labelHeight) / 2), self.lgf_width - (self.style.lgf_BetweenIconAndMessage * 3 + self.messageIcon.lgf_width), labelHeight);
}

@end

@implementation UIViewController (LGFTopBarMessage)

static char TopMessageKey;

- (void)lgf_ShowTopMessage:(NSString *)message {
    LGFTopMessageStyle *style = [LGFTopMessageStyle na];
    style.lgf_Message = message;
    [self lgf_ShowTopMessageWithStyle:style withTapBlock:nil];
}

- (void)lgf_ShowTopMessageWithStyle:(LGFTopMessageStyle *)style  withTapBlock:(dispatch_block_t)tapHandler {
    // 首先判断 self 是否已经全部加载完毕
    if ([self isViewLoaded] && self.view.window) {
        [self showMessageWithStyle:style withTapBlock:tapHandler];
    } else {
        // 如果是lgf_Overlay 因为不改变父视图位置, 所以无需等待父视图加载完毕
        if (style.lgf_MessageMode == lgf_Overlay) {
            [self showMessageWithStyle:style withTapBlock:tapHandler];
        }
        NSAssert(style.lgf_MessageMode == lgf_Overlay, @"父视图未加载完毕, 无法使用lgf_Resize ,因为lgf_Resize将改变父视图位置, 为确保父视图已经加载完毕, 请在父视图viewDidAppear方法中添加 (lgf_ShowTopMessage...)方法");
    }
}

- (void)showMessageWithStyle:(LGFTopMessageStyle *)style  withTapBlock:(dispatch_block_t)tapHandler {
    // 判断 Y 点
    CGFloat startY = 0.0;
    if (self.navigationController.navigationBar.translucent) {
        startY = 64.0;
    } else {
        startY = 0.0;
    }
    
    // 获取 label 的高度 LGFTopMessageView 的高度等于 label的高度 + lgf_topBarSpacingHeight
    CGFloat labelWidth = self.view.lgf_width - (style.lgf_BetweenIconAndMessage * 3 + style.lgf_IconWidth);
    CGFloat labelHeight = MIN([style.lgf_Message lgf_HeightWithFont:style.lgf_MessageLabelFont constrainedToWidth:labelWidth], [@"" lgf_HeightWithFont:style.lgf_MessageLabelFont constrainedToWidth:labelWidth] * style.lgf_LabelMaxLine);
    
    // 动态加载 LGFTopMessageView 防止其他视图控制器添加无用属性
    LGFTopMessageView *topMessageV = objc_getAssociatedObject(self, &TopMessageKey);
    topMessageV = [LGFTopMessageView sharedshard];
    topMessageV.frame = CGRectMake(0, startY - (style.lgf_TopBarSpacingHeight + labelHeight), CGRectGetWidth(self.view.bounds), style.lgf_TopBarSpacingHeight + labelHeight);
    objc_setAssociatedObject(self, &TopMessageKey, topMessageV, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    topMessageV.tapHandler = tapHandler;
    topMessageV.style = style;
    [self.view addSubview:topMessageV];
    
    // 隐藏之前取消延迟
    [NSObject cancelPreviousPerformRequestsWithTarget:topMessageV];
    
    // 延迟隐藏
    if (style.lgf_DimissDelay > 0) {
        [topMessageV performSelector:@selector(dismiss) withObject:nil afterDelay:style.lgf_DimissDelay + style.lgf_AnimateDuration];
    } else {
        if (style.lgf_MessageMode == lgf_Resize) {
            [topMessageV performSelector:@selector(dismiss) withObject:nil afterDelay:1.0 + style.lgf_AnimateDuration];
        }
    }
    
    // 执行显示动画
    [UIView animateWithDuration:style.lgf_AnimateDuration animations:^{
        if (style.lgf_MessageMode == lgf_Resize) {
            CGAffineTransform transform = CGAffineTransformMakeTranslation(0, style.lgf_TopBarSpacingHeight + labelHeight);
            self.view.transform = transform;
        } else {
            topMessageV.lgf_y = startY;
        }
    }];
}

- (void)lgf_DismissTopMessage {
    NSArray *subViews = self.view.subviews;
    for (UIView *subView in subViews) {
        if ([subView isKindOfClass:[LGFTopMessageView class]]) {
            LGFTopMessageView *view = (LGFTopMessageView *)subView;
            [view dismiss];
        }
    }
}

@end

@implementation LGFTopMessageStyle

- (instancetype)init {
    self = [super init];
    // 默认配置
    self.lgf_MessageBackColor = [UIColor lgf_ColorWithHexString:@"FBF9FA"];
    self.lgf_MessageTextColor = [UIColor blackColor];
    self.lgf_MessageLabelFont = [UIFont systemFontOfSize:15];
    self.lgf_MessageIcon = nil;
    self.lgf_LabelMaxLine = 1;
    self.lgf_MessageMode = lgf_Overlay;
    self.lgf_DimissDelay = 2.0;
    self.lgf_Message = @"";
    self.lgf_IconWidth = 20.0;
    self.lgf_BetweenIconAndMessage = 10.0;
    self.lgf_AnimateDuration = 0.3;
    self.lgf_TopBarSpacingHeight = 20.0;
    return self;
}

+ (instancetype)na {
    LGFTopMessageStyle *style = [[LGFTopMessageStyle alloc] init];
    return style;
}

@end

具体使用:

LGFTopMessageStyle *style = [LGFTopMessageStyle na];
    style.lgf_Message = @"来国锋发的消息息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息la的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我发的消息label发的消息lab发息我b发息我发的消息label发的消息l";
    style.lgf_MessageMode = lgf_Resize;
    style.lgf_LabelMaxLine = 4;
    style.lgf_IconWidth = 40;
    style.lgf_MessageIcon = [UIImage imageNamed:@"testIcon"];
    style.lgf_MessageLabelFont = [UIFont systemFontOfSize:15];
    [self lgf_ShowTopMessageWithStyle:style withTapBlock:^{
        NSLog(@"点击了")
    }];

附加单列宏实现

// 添加到 .h 文件
#define lgf_AllocOnlyOnceForH(methodName) + (instancetype)shared##methodName
// 添加到 .m 文件
#define lgf_AllocOnlyOnceForM(name,methodName) static name* _instance;\
+ (instancetype)allocWithZone:(struct _NSZone *)zone\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super allocWithZone:zone];\
});\
return _instance;\
}\
\
+ (instancetype)shared##methodName{\
\
return [[name alloc] init];\
}\
- (instancetype)init{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super init];\
});\
return _instance;\
}\
\
- (instancetype)copyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
- (instancetype)mutableCopyWithZone:(NSZone *)zone\
{\
return _instance;\
}

效果展示:


轻量的顶部提示栏分类_第1张图片
WechatIMG1.jpeg

你可能感兴趣的:(轻量的顶部提示栏分类)