iOS开发——无网占位图的实现

https://www.jianshu.com/p/d537393fe247

 https://github.com/wyzxc/CQPlaceholderView
https://github.com/wyzxc/TableViewNoContentView

先来看一下实际效果:

 
效果.gif

为什么要使用无网占位图?

为了更好地用户体验。难道没网的时候展示一个空白模板?当然,无网占位图也是一个APP最基本的功能只一。

原理简介:

viewWillAppear时判断是否有网,如果没网,展示无网占位图。点击无网占位图上的重新查看按钮,判断是否有网,如果没网,toast提示。如果有网,移除无网占位图,重新加载数据。

详细讲解:

  • 首先按照设计师的UI图封装一个无网占位图view:CQNoNetworkView,在构造方法里完成
- (instancetype)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        // UI搭建
        [self setUpUI];
    }
    return self;
}
   /** UI搭建 */
  - (void)setUpUI{
    self.backgroundColor = [UIColor whiteColor];
    
    // 404图片放中间
    UIImageView *noNetworkImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 125, 125)];
    noNetworkImageView.center = CGPointMake(self.width / 2, self.height / 2);
    [self addSubview:noNetworkImageView];
    noNetworkImageView.image = [UIImage imageNamed:@"404notfound"];
    
    // 重新查看按钮
    UIButton *checkButton = [[UIButton alloc]initWithFrame:CGRectMake(0, noNetworkImageView.maxY + 24, 115, 30)];
    checkButton.centerX = self.width / 2;
    [self addSubview:checkButton];
    [checkButton.titleLabel setFont:[UIFont systemFontOfSize:15]];
    checkButton.backgroundColor = [UIColor colorWithRed:0.00 green:0.76 blue:0.66 alpha:1.00];
    [checkButton setTitle:@"重新查看" forState:UIControlStateNormal];
    [checkButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [checkButton addTarget:self action:@selector(checkNetworkButtonClicked) forControlEvents:UIControlEventTouchUpInside];
    
    // 图片上面的两个label
    UILabel *label1 = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 20)];
    label1.text = @"刷新一下返回店铺!";
    label1.font = [UIFont systemFontOfSize:14];
    label1.textColor = [UIColor colorWithRed:0.00 green:0.77 blue:0.68 alpha:1.00];
    label1.backgroundColor = [UIColor clearColor];
    label1.textAlignment = NSTextAlignmentCenter;
    [label1 sizeToFit];
    label1.centerX = self.width / 2;
    label1.maxY = noNetworkImageView.y - 21;
    [self addSubview:label1];
    
    UILabel *label2 = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 15)];
    label2.text = @"您似乎迷路了";
    label2.font = [UIFont systemFontOfSize:19];
    label2.textColor = [UIColor colorWithRed:0.00 green:0.77 blue:0.67 alpha:1.00];
    label2.backgroundColor = [UIColor clearColor];
    label2.textAlignment = NSTextAlignmentCenter;
    [label2 sizeToFit];
    label2.centerX = self.width / 2;
    label2.maxY = label1.y - 12;
    [self addSubview:label2];
}

  • 处理“重新查看”按钮的逻辑,基本思路是:点击此按钮时,判断是否有网,如果仍旧没网,弹出toast提示用户;如果有网,移除此view,并且,让代理方执行相应代理方法,比如说,重新加载数据。
 /** 重新查看按钮点击 */
  - (void)checkNetworkButtonClicked{
    if ([DateUtil isNetWorkRunning]) {
        // 如果有网,view消失,并且让代理方执行代理方法
        for (CQNoNetworkView *view in [self getCurrentViewController].view.subviews) {
            if ([view isMemberOfClass:[CQNoNetworkView class]]) {
                [view removeFromSuperview];
            }
        }
        
        // 重新加载数据
        if ([self.delegate respondsToSelector:@selector(reloadData)]) {
            [self.delegate reloadData];
        }
    }else{
        // 如果没网,toast提示
        [CQHud showToastWithMessage:@"请检查你的网络连接"];
    }
}

  • 确定代理方法(点击“重新加载”按钮时,代理方执行的方法),我的是重新加载数据。
@protocol CheckNetworkDelegate <NSObject>
@optional

  /** 重新加载数据 */
  - (void)reloadData;

@end

  /** 无网络时展示的view */
@interface CQNoNetworkView : UIView

@property (nonatomic,weak) id<CheckNetworkDelegate> delegate;

@end

  • 确定代理方。代理方就是执行“重新加载数据”的对象。由于每个viewController都需要在无网时展示无网占位图,所以代理方可以设置为项目的BaseViewController(不要告诉我,你的项目里没有基类😅)
@interface BaseViewController ()<CheckNetworkDelegate>

在基类里实现重新加载数据,当然,需要由子类重写,不过如果你的项目架构的比较好,所有viewcontroller的获取数据的方法的方法名都一样,那么就不需要再由子类重写了:

/** 重新加载数据,由子类重写 */
     (void)reloadData{
    
}

同样在基类里实现弹出无网占位图的方法:

/** 显示无网络view */
- (void)showNoNetworkView{
    // 将导航栏和tabbar留出来
    CQNoNetworkView *noNetworkView = [[CQNoNetworkView alloc]initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight - 49)];
    noNetworkView.delegate = self;
    [self.view addSubview:noNetworkView];
}
  • 在基类的viewWillAppear:里判断网络情况:
// 如果没网,加载无网占位图
    if (![DateUtil isNetWorkRunning]) {
        // 无网加载无网站位图
        [self showNoNetworkView];
    }else{
        // 有网移除所有无网展位图
        for (CQNoNetworkView *view in self.view.subviews) {
            if ([view isMemberOfClass:[CQNoNetworkView class]]) {
                [view removeFromSuperview];
            }
        }
    }
  • 最后,在你的子类里重写“重新加载数据”方法即可:
- (void)reloadData{
    [self getData];
}

总结

此功能主要是代理和基类的运用,合理使用基类能让你少些很多代码。当然有些APP可能不仅有一种网络占位图,这个时候在子类里重写基类里的showNoNetworkView方法即可。以上是我对此功能的一些个人看法,只是简单的实现了这个功能,具体项目中还是要根据项目需求进行必要修改和优化的。但是,思路基本上不变。欢迎各位看官提出意见或建议。

补充两个更加优雅和强大的Demo

UITableView空数据占位图
适用于任何场景的通用占位图



作者:无夜之星辰
链接:https://www.jianshu.com/p/d537393fe247
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
posted @ 2018-08-10 08:59  sundaysios  阅读(664)  评论(0编辑  收藏  举报