缺省页-空视图-站位视图

2018-09-17  本文已影响86人  羊妞麻麻

需求如下:


屏幕快照 2018-09-17 下午2.41.31.png

在每个项目中,都会在请求数据为空或者网络不好的时候,提示用户当前网络状态的占位图。已达到效果和美观上都给人比较好的提示。以前都是针对不同场景展示不同的站位图片,每个用到的地方,都要自己写一遍空视图。由于该项目中用到的地方比较多,所以封装了出来。使用者,直接传入想对应页面的占位图枚举参数即可。不需要增加太多的代码。

思路:

第一种:空视图无非就是一个View 和一个用于展示文案的UILabel。
第二种:空视图还可以展示一个view+一个用于刷新试图的UIButton 按钮。

·首先我们需要封装一个无数据占位图

一个项目中,无数据占位图不光只有一种,但是可以看到他们的布局是非常相似的,所以我的做法是根据不同的值,创建不同的UI。

首先先要定一个一个枚举
typedef enum{
    TimeOutEmptyType = 0,             //    网络请求超时
    NoneSearchDataEmptyType,          //    暂无搜索结果
    NoneDataEmptyType,                //    暂无数据
    ErrorEmptyType,                   //    页面出错啦~
    LocationErrorEmptyType,           //    无法获取位置信息
    NoNetWorkEmptyType,               //    网络无法连接
    NoShopAssitantType,               //    没有店铺助理
    NoInspectionTemplateType,         //    没有巡检模版
    NoInspectionTaskType,             //    没有巡检任务
    NOOpenDoorDataType,               //    没有开门数据
    NoneVisitorType,                  //    没有拜访者数据
    NORepairRecordDataType,           //    没有维修记录
    NOEMRecordDataType,               //    没有保养记录
    NoBlueToothDoor,                  //    没有附近的门
    NoDeviceSelect,                   //    没有选择设备
    NoNoticeType,                     //    没有通知记录
    NoAnnounceType,                   //    没有公告记录
    NoPaymentType,                    //    没有收费记录
    NoTicketType                      //    没有工单待办记录

}EmptyType;

当然这肯定不是项目中全部的空视图,它会根据业务需求不断的增加。
.h

@interface SCEmptyView : UIView
@property (nonatomic, strong) UIImageView *emptyImage;
@property (nonatomic, strong) UILabel *titleLab;
@property (nonatomic, strong) UILabel *subTitleLab;
@property (nonatomic, strong) UIButton* retryBtn;

提供两个类方法,用于直接创建空视图。

+ (SCEmptyView*)defaultEmptyView;
+ (SCEmptyView*)emptyViewWithImage:(UIImage*)img title:(NSString*)title subTitle:(NSString*)subTitle;

初始化空界面,返回自定义空数据View

/*!
 *  @author wyy
 *
 *  @brief 初始化空界面
 *
 *  @param icon     图标
 *  @param title    标题
 *  @param subTitle 副标题
 *  @param btnTitle 按钮文字
 *
 *  @return 返回自定义空数据View
 */
- (SCEmptyView*)initWithFrame:(CGRect)frame icon:(NSString*)icon title:(NSString*)title subTitle:(NSString*)subTitle buttonTitle:(NSString *)btnTitle;

根据空数据原因类型获取空界面,返回空数据View

+ (SCEmptyView*)emptyViewWithType:(EmptyType)emptyType frame:(CGRect)frame;

ok 那就来看一下具体实现吧。.m

@implementation SCEmptyView

- (UIView *)initWithIcon:(NSString *)icon Title:(NSString *)title ButtonTitle:(NSString *)btnTitle OtherTitles:(NSArray *)titles
{
    if (self = [self init]) {
        self.frame = CGRectMake(0, 0, kSCREEN_WIDTH, kSCREEN_HEIGHT);
        self.tag = 65535;
        CGFloat wh = 130;
        UIImageView *imgView=[[UIImageView alloc] initWithFrame:CGRectMake(kSCREEN_WIDTH*0.5-wh*0.5, 85, wh, wh)];
        if (icon != nil && ![icon isEqualToString:@""]) {
            [imgView setImage:[UIImage imageNamed:icon]];
        }
        [self addSubview:imgView];
        
        UILabel *textLabel=[[UILabel alloc] initWithFrame:CGRectMake(15, CGRectGetMaxY(imgView.frame) + 10, kSCREEN_WIDTH - 2*15, 18)];
        textLabel.textAlignment=NSTextAlignmentCenter;
        textLabel.textColor = [UIColor blackColor];
        textLabel.font = [UIFont systemFontOfSize:17];
        textLabel.numberOfLines = 0;
        textLabel.text = title;
        [textLabel sizeToFit];
        textLabel.center = CGPointMake(self.center.x, textLabel.center.y);
        
        [self addSubview:textLabel];
        
        if (titles.count > 0) {
            for (NSString *titleStr in titles) {
                
                textLabel=[[UILabel alloc] initWithFrame:CGRectMake(15, CGRectGetMaxY(textLabel.frame)+10 , kSCREEN_WIDTH - 2*15, 15)];
                textLabel.textAlignment=NSTextAlignmentCenter;
                textLabel.textColor = [UIColor blackColor];
                textLabel.font=[UIFont systemFontOfSize:14];
                textLabel.text = titleStr;
                textLabel.numberOfLines = 0;
                [textLabel sizeToFit];
                textLabel.center = CGPointMake(self.center.x, textLabel.center.y);
                [self addSubview:textLabel];
            }
        }
        
        if (btnTitle != nil && ![btnTitle isEqualToString:@""]) {
            UIButton *addNewBtn = [[UIButton alloc] initWithFrame:CGRectMake(kSCREEN_WIDTH*0.5-60, CGRectGetMaxY(textLabel.frame) + 5, 120, 38)];
            [addNewBtn setTitle:btnTitle forState:UIControlStateNormal];
            [addNewBtn setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
            addNewBtn.titleLabel.font = [UIFont systemFontOfSize:17];
             
            [addNewBtn addTarget:self action:@selector(btnClicked) forControlEvents:UIControlEventTouchUpInside];
            [self addSubview:addNewBtn];
        }
        self.backgroundColor = [UIColor SCBackGroundColor];
    }
    return self;
}

初始化

- (id)init {
    self = [super init];
    if (self) {
        [self initViews];
    }
    return self;
}

- (void)initViews {
    _emptyImage = [[UIImageView alloc] init];
    [self addSubview:_emptyImage];
    
    _titleLab = [[UILabel alloc] init];
    _titleLab.textAlignment = NSTextAlignmentCenter;
    _titleLab.textColor = COLOR(124,121,122,1);
    _titleLab.font = [UIFont systemFontOfSize:17];
    [self addSubview:_titleLab];
    
    _subTitleLab = [[UILabel alloc] init];
    _subTitleLab.textAlignment = NSTextAlignmentCenter;
    _subTitleLab.textColor = [UIColor greenColor];
    _subTitleLab.font = [UIFont systemFontOfSize:14];
    [self addSubview:_subTitleLab];
    
    [_emptyImage mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.mas_centerX);
        make.top.equalTo(self.mas_top).with.offset(85);
        make.width.mas_equalTo(130);
        make.height.mas_equalTo(130);
    }];
    [_titleLab mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(_emptyImage.mas_bottom).with.offset(10);
        make.left.equalTo(self.mas_left).with.offset(15);
        make.right.equalTo(self.mas_right).with.offset(-15);
        make.height.mas_equalTo(18);
    }];
    [_subTitleLab mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(_titleLab.mas_bottom).with.offset(10);
        make.left.equalTo(self.mas_left).with.offset(15);
        make.right.equalTo(self.mas_right).with.offset(-15);
        make.height.mas_equalTo(15);
    }];
}

默认的空视图

+ (SCEmptyView*)defaultEmptyView {
    
    if ([[SCAppInitialize shareInstance] checkNetStatus] ==AFNetworkReachabilityStatusReachableViaWiFi || [[SCAppInitialize shareInstance] checkNetStatus] ==AFNetworkReachabilityStatusReachableViaWWAN || [[SCAppInitialize shareInstance] checkNetStatus] ==AFNetworkReachabilityStatusUnknown) {
        return [[SCEmptyView alloc] initWithIcon:@"ic_no_ticket" Title:@"暂无数据" ButtonTitle:nil OtherTitles:nil];
    }else{
        //无网络
        
        return [[SCEmptyView alloc] initWithIcon:@"" Title:@"网络无法连接" ButtonTitle:@"重试" OtherTitles:[NSArray arrayWithObjects:@"请检查你的手机是否连联网", nil]];
    }
    
}
+ (SCEmptyView*)emptyViewWithImage:(UIImage*)img title:(NSString*)title subTitle:(NSString*)subTitle {
    SCEmptyView *emptyView = [[SCEmptyView alloc] init];
    emptyView.emptyImage.image = img;
    emptyView.titleLab.text = title;
    emptyView.subTitleLab.text = subTitle;  
    return emptyView;
}
- (SCEmptyView*)initWithFrame:(CGRect)frame icon:(NSString*)icon title:(NSString*)title subTitle:(NSString*)subTitle buttonTitle:(NSString *)btnTitle;{
    self = [super initWithFrame:frame];
    if (self) {
        //空图标
        _emptyImage = [[UIImageView alloc] initWithFrame:CGRectMake((self.width-130)/2, 75, 130, 130)];
        _emptyImage.image = [UIImage imageNamed:icon];
        _emptyImage.contentMode = UIViewContentModeScaleAspectFit;
        [self addSubview:_emptyImage];
        
        //显示标题
        _titleLab = [[UILabel alloc] initWithFrame:CGRectMake(15, _emptyImage.bottom+10, self.width-2*15, 22)];
        _titleLab.textAlignment = NSTextAlignmentCenter;
        _titleLab.textColor = [UIColor blackColor];
        _titleLab.font = [UIFont systemFontOfSize:16];
        _titleLab.text = title;
        [self addSubview:_titleLab];
        
        //重试按钮的顶部位置
        CGFloat top = _titleLab.bottom;
        
        //显示副标题
        _subTitleLab = [[UILabel alloc] initWithFrame:CGRectMake(15, _titleLab.bottom+10, self.width-2*15, 0)];
        _subTitleLab.textAlignment = NSTextAlignmentCenter;
        _subTitleLab.textColor = [UIColor blackColor];
        _subTitleLab.font = [UIFont systemFontOfSize:12];
        [self addSubview:_subTitleLab];
        
        if (subTitle.length > 0) {
            _subTitleLab.text = subTitle;
            _subTitleLab.height = 16;
            top = _subTitleLab.bottom;
        }
        
        //重试按钮
        _retryBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        _retryBtn.frame = CGRectMake((self.width-100)/2, top+15, 118, 30);
        [_retryBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [_retryBtn setBackgroundColor:[UIColor SCBlueColor]];
        _retryBtn.titleLabel.font = [UIFont systemFontOfSize:13];
        [_retryBtn addTarget:self action:@selector(btnClicked) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:_retryBtn];
        
        if (btnTitle.length > 0) {
            [_retryBtn setTitle:btnTitle forState:UIControlStateNormal];
        }else{
            _retryBtn.hidden = YES;
        }
        
    }
    return self;
}

一般我都会采用下面的方法来创建空视图

+ (SCEmptyView*)emptyViewWithType:(EmptyType)emptyType frame:(CGRect)frame{
    if (emptyType == NoneDataEmptyType) {
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"ic_no_ticket" title:@"您还没有工单哦" subTitle:@"" buttonTitle:@"返回"];
    }else if (emptyType == ErrorEmptyType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"" title:@"页面出错啦~" subTitle:@"" buttonTitle:@""];
    }else if (emptyType == NoNetWorkEmptyType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"" title:@"网络无法连接" subTitle:@"请检查你的手机是否联网" buttonTitle:@"重试"];
    }else if (emptyType == TimeOutEmptyType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"" title:@"网络请求超时" subTitle:@"" buttonTitle:@"重试"];
    }else if (emptyType == NoneSearchDataEmptyType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"" title:@"暂无搜索结果" subTitle:@"" buttonTitle:@""];
    }else if (emptyType == LocationErrorEmptyType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"" title:@"无法获取位置信息" subTitle:@"" buttonTitle:@"重试"];
    }else if(emptyType == NoInspectionTemplateType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"scInspectionEmptyIcon" title:@"" subTitle:@"目前暂无可以选择的设备及对应的巡检模板" buttonTitle:@""];
    }else if(emptyType == NoInspectionTaskType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"scInspectionEmptyTaskIcon" title:@"" subTitle:@"你还没有巡检任务" buttonTitle:@""];
    }else if(emptyType == NOOpenDoorDataType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"zanwumen" title:@"" subTitle:@"暂无您可通行的门" buttonTitle:@""];
    }else if(emptyType == NORepairRecordDataType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"NORepairRecordImage" title:@"" subTitle:@"暂无维修记录" buttonTitle:@""];
    }else if(emptyType == NoBlueToothDoor){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"bluetooth" title:@"暂无附近的门" subTitle:@"" buttonTitle:@""];
    }else if(emptyType == NOEMRecordDataType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"NOEMRecordImage" title:@"" subTitle:@"暂无保养记录" buttonTitle:@""];
    }else if(emptyType == NoDeviceSelect){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"sc_noDevices" title:@"目前暂无设备" subTitle:@"" buttonTitle:@""];
    }else if(emptyType == NoNoticeType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"NOEMRecordImage" title:@"暂无通知数据" subTitle:@"" buttonTitle:@""];
    }else if(emptyType == NoAnnounceType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"NOEMRecordImage" title:@"暂无公告数据" subTitle:@"" buttonTitle:@""];
    }else if(emptyType == NoPaymentType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"NOEMRecordImage" title:@"暂无收费数据" subTitle:@"" buttonTitle:@""];
    }else if(emptyType == NoTicketType){
        return [[SCEmptyView alloc] initWithFrame:frame icon:@"NOEMRecordImage" title:@"暂无工单待办数据" subTitle:@"" buttonTitle:@""];
    }
    return nil;
}

- (void)btnClicked
{
    if (_btnClick != nil) {
        self.btnClick();
    }
}

具体VC中加载空视图的使用方式如下:

-(SCEmptyView *)emptyView{
    if (!_emptyView) {
        _emptyView = [SCEmptyView emptyViewWithType:NoNoticeType frame:self.view.frame];
    }
    return _emptyView;
}

比如我在Tabelview上面加载一个空视图,就可以用上面的方式加载View。然后根据数据来管理是否隐藏和展示。

[self.tableView setBackgroundView:self.interactor.dataArrayM.count?[UIView new]:self.emptyView];

或者

第一步:
#pragma mark lazy loading
-(SCEmptyView *)emptyView{
    if(!_emptyView){
        _emptyView = [SCEmptyView emptyViewWithType:NoInspectionTaskType frame:CGRectMake(0, 50, kSCREEN_WIDTH, kSCREEN_HEIGHT)];
        _emptyView.hidden = YES;
    }
    return _emptyView;
}
第二步:
    [self.view addSubview:self.emptyView];
第三步:
    self.emptyView.hidden = self.interactor.dataArrayM.count?YES:NO;

以上就是针对项目中常用到的占位图做了一个简单的封装。

上一篇下一篇

猜你喜欢

热点阅读