https://blog.csdn.net/chmod_r_755/article/details/53231461

俗话说的好,傻逼的APP都是相似的,牛逼的APP各有各的牛逼。。。但是UITableView的这个三种状态的默认界面不知道困扰了多少人。。

github上有一个哥们写了一个牛逼的框架:https://github.com/dzenbot/DZNEmptyDataSet,但是本人发现本人不太牛逼,无法驾驭这个牛逼的框架。。 所以本人自己琢磨了一套出来了。。 先上效果图吧 。。

这是一张正常的列表,有数据显示正常的

接下来我们显示几张不正常的,数据正在请求

接下来我们显示几张不正常的,没有网络

接下来我们显示几张不正常的,没有数据

看到这里了你大概猜到我写这篇微博的中心思想了,本人不喜欢扯神马设计模式神马MVC模式,听到某些傻逼的面试官问MVC的时候,我不得不吐槽一把,面试官先生你怎么理解MVC设计模式了 ?

我的设计思路是 使用OC中的代理,也就是Java里面的面向接口编程,扯远了。。。

首先,我的这个LoadingView很明显是加在UITableView或UICollectionView上面的,也就是,在UITableView或UICollectionView上加入了一层View,也就是LoadingView

但是,问题来了, 现在有三个View,第一个是 数据正在加载的时候的View,第二个是没有网络的View, 第三个是没有数据的View, 三个View应该是互斥的,并且三个View都跟数据源有关系, 也就是加入列表中有数据的话,三个View是不显示的。。。而且这三个View最好是让子类重写,别问我问什么,碰到某些变态的设计师,收藏界面A一种View,收藏B一种View,你懂得。。 而且这些视图显示还跟数据有关系,所以必须设置视图代理和数据代理让子类重写

那么我们必须提供一种让子类重写的方法,OC里面当然是用代理了

  1.  
    @protocol LoadingDataViewDelegate <NSObject>
  2.  
     
  3.  
    @required
  4.  
    -(nullable UIView *)loadingDataViewWithNodata:(nullable LoadingDataView *)parent ;
  5.  
    @required
  6.  
    -(nullable UIView *)loadingDataViewWithNoNet:(nullable LoadingDataView *)parent ;
  7.  
    @required
  8.  
    -(nullable UIView *)loadingDataViewWithLoading:(nullable LoadingDataView *)parent ;
  9.  
     
  10.  
    @required
  11.  
    -(nullable NSArray *)loadingDataViewBindArrarys:(nullable LoadingDataView *)parent;
  12.  
     
  13.  
    @end
  14.  
     

话又说回来,视图必须把代理和容器(UITableView 或 UICollectionView)链接起来,而且需要告诉容器一些事件,什么时候开始请求,什么时候结束请求

  1.  
    @interface LoadingDataView : UIView
  2.  
     
  3.  
    -(nullable id)initSrollView:(nullable UIScrollView *)scrollView delegate:(id<LoadingDataViewDelegate>)delegate;
  4.  
     
  5.  
    @property (nonatomic, weak, nullable) id <LoadingDataViewDelegate> delegate;
  6.  
     
  7.  
    -(void)startShowView;
  8.  
    -(void)endShowView:(NSError *)error responese:(id)response;

也就这里暴露了两个方法,开始请求&结束请求

上面我说过,需要子类重写三个界面,正在加载,没有数据,没有网络,而且这个三个界面是互斥的(互斥什么意思自己百度去)

我的做法是将三个View一次加在LoadingView上,然后把LoadingView加在UITableView或UICollectionView上,代码奉上

  1.  
    @implementation LoadingDataView{
  2.  
     
  3.  
     
  4.  
    UIView *noDataView;
  5.  
    UIView *noNetView;
  6.  
    UIView *loadingView;
  7.  
    NSArray *arrList;
  8.  
     
  9.  
     
  10.  
    }
  11.  
     
  12.  
     
  13.  
    -(nullable id)initSrollView:(nullable UIScrollView *)scrollView delegate:(id<LoadingDataViewDelegate>)delegate{
  14.  
     
  15.  
    if (self=[super init]) {
  16.  
    self.delegate=delegate;
  17.  
     
  18.  
     
  19.  
    arrList=[delegate loadingDataViewBindArrarys:self];
  20.  
     
  21.  
    self.frame=CGRectMake(0, 0, scrollView.frame.size.width, scrollView.frame.size.height);
  22.  
     
  23.  
    noDataView=[delegate loadingDataViewWithNodata:self ];
  24.  
    noNetView=[delegate loadingDataViewWithNoNet:self ];
  25.  
    loadingView=[delegate loadingDataViewWithLoading:self ];
  26.  
     
  27.  
    [self addSubview:noDataView];
  28.  
    [self addSubview:noNetView];
  29.  
    [self addSubview:loadingView];
  30.  
     
  31.  
    [self showLoadingView];
  32.  
     
  33.  
     
  34.  
    }
  35.  
     
  36.  
     
  37.  
    [scrollView addSubview:self];
  38.  
     
  39.  
    return self;
  40.  
     
  41.  
     
  42.  
     
  43.  
    }
  44.  
     
  45.  
     
  46.  
    -(void)showLoadingView{
  47.  
    self.hidden=NO;
  48.  
    loadingView.hidden=NO;
  49.  
    noNetView.hidden=YES;
  50.  
    noDataView.hidden=YES;
  51.  
    }
  52.  
     
  53.  
    -(void)showNoNetView{
  54.  
    self.hidden=NO;
  55.  
    loadingView.hidden=YES;
  56.  
    noNetView.hidden=NO;
  57.  
    noDataView.hidden=YES;
  58.  
    }
  59.  
    -(void)showNoDataView{
  60.  
    self.hidden=NO;
  61.  
    loadingView.hidden=YES;
  62.  
    noNetView.hidden=YES;
  63.  
    noDataView.hidden=NO;
  64.  
    }
  65.  
     
  66.  
    -(void)showNormalView{
  67.  
    self.hidden=YES;
  68.  
     
  69.  
    }
  70.  
     
  71.  
    -(void)startShowView{
  72.  
     
  73.  
     
  74.  
    if (arrList.count==0) {
  75.  
    [self showLoadingView];
  76.  
    }else{
  77.  
    [self showNoNetView];
  78.  
    }
  79.  
     
  80.  
    }
  81.  
     
  82.  
    -(void)endShowView:(NSError *)error responese:(id)response{
  83.  
    if (error==nil) {
  84.  
     
  85.  
    if ([arrList count]==0) {
  86.  
    [self showNoDataView];
  87.  
    }else{
  88.  
    [self showNormalView];
  89.  
    }
  90.  
     
  91.  
     
  92.  
    }else{
  93.  
     
  94.  
    if ([arrList count]==0) {
  95.  
    [self showNoNetView];
  96.  
    }else{
  97.  
    [self showNormalView];
  98.  
    }
  99.  
    }
  100.  
     
  101.  
     
  102.  
    }
  103.  
    -(nullable NSArray *)loadingDataViewBindArrarys:(nullable LoadingDataView *)parent{
  104.  
     
  105.  
    return [self.delegate loadingDataViewBindArrarys:parent];
  106.  
     
  107.  
    }
  108.  
     
  109.  
    -(UIView *)nodataView:(LoadingDataView *)parent {
  110.  
     
  111.  
    return [self.delegate loadingDataViewWithNoNet:parent];
  112.  
    }
  113.  
    -(UIView *)nonetView:(LoadingDataView *)parent {
  114.  
     
  115.  
     
  116.  
    return [self.delegate loadingDataViewWithNoNet:parent];
  117.  
    }
  118.  
    -(UIView *)loadingView:(LoadingDataView *)parent {
  119.  
     
  120.  
    return [self.delegate loadingDataViewWithLoading:parent];
  121.  
    }
  122.  
     
  123.  
    @end

现在LoadingView这个类我们已经处理完了, 那么怎么使用了  ?首先,我建议你写一个BaseViewController,每个类都继承这个BaseViewCotroller,当然我只是建议,如果你不这么干,也可以,农夫山泉建议零售价2元,很多小店就不按建议卖。然后像这样

  1.  
    #import <UIKit/UIKit.h>
  2.  
    #import "LoadingDataViewDelegate.h"
  3.  
     
  4.  
    @interface BaseViewController : UIViewController<LoadingDataViewDelegate>
  5.  
     
  6.  
    @end

并重写代理方法

  1.  
    #import "BaseViewController.h"
  2.  
     
  3.  
     
  4.  
     
  5.  
    @interface BaseViewController ()
  6.  
     
  7.  
    @end
  8.  
     
  9.  
    @implementation BaseViewController
  10.  
     
  11.  
    - (void)viewDidLoad {
  12.  
    [super viewDidLoad];
  13.  
    // Do any additional setup after loading the view.
  14.  
     
  15.  
     
  16.  
    }
  17.  
    -(nullable NSArray *)loadingDataViewBindArrarys:(nullable LoadingDataView *)parent{
  18.  
     
  19.  
     
  20.  
    return nil;
  21.  
     
  22.  
    }
  23.  
     
  24.  
     
  25.  
    -(UIView *)loadingDataViewWithNoNet:(LoadingDataView *)parent{
  26.  
     
  27.  
     
  28.  
    UIView *vi=[[UIView alloc] init];
  29.  
    vi.frame=CGRectMake(0, 0, parent.frame.size.width, parent.frame.size.height);
  30.  
    vi.backgroundColor=[UIColor cyanColor];
  31.  
     
  32.  
    return vi;
  33.  
    }
  34.  
     
  35.  
     
  36.  
     
  37.  
    -(UIView *)loadingDataViewWithNodata:(LoadingDataView *)parent{
  38.  
     
  39.  
    UIView *vi=[[UIView alloc] init];
  40.  
    vi.frame=CGRectMake(0, 0, parent.frame.size.width, parent.frame.size.height);
  41.  
    vi.backgroundColor=[UIColor redColor];
  42.  
    return vi;
  43.  
     
  44.  
     
  45.  
    }
  46.  
    -(UIView *)loadingDataViewWithLoading:(LoadingDataView *)parent{
  47.  
     
  48.  
    UIView *vi=[[UIView alloc] init];
  49.  
    vi.frame=CGRectMake(0, 0, parent.frame.size.width, parent.frame.size.height);
  50.  
    vi.backgroundColor=[UIColor yellowColor];
  51.  
    return vi;
  52.  
     
  53.  
    }
  54.  
     
  55.  
     
  56.  
    - (void)didReceiveMemoryWarning {
  57.  
    [super didReceiveMemoryWarning];
  58.  
    // Dispose of any resources that can be recreated.
  59.  
    }

神马意思了。。这就是最基本的没有网络,没有数据,和加载数据的界面,你重写神马样的都可以,如果你的全局三种默认界面都是一样的话,你只需要在这个基类中重写一次就可以。

然后,如何把LoadingView ,数据,和容器关联起来了  ?

我把http请求稍稍封装了下, 如果不熟悉block自己百度。。。

源码如下

  1.  
    @interface TestViewController ()<UITableViewDataSource,UITableViewDelegate>{
  2.  
     
  3.  
    UITableView *table;
  4.  
     
  5.  
    LoadingDataView *loadingView;
  6.  
    NSMutableArray *arrList;
  7.  
     
  8.  
     
  9.  
     
  10.  
    }
  11.  
     
  12.  
    @end
  13.  
     
  14.  
    @implementation TestViewController
  15.  
     
  16.  
    - (void)viewDidLoad {
  17.  
    [super viewDidLoad];
  18.  
     
  19.  
    arrList=[[NSMutableArray alloc] init];
  20.  
    // Do any additional setup after loading the view.
  21.  
    table=[[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)];
  22.  
    table.delegate=self;
  23.  
    table.dataSource=self;
  24.  
    [self.view addSubview:table];
  25.  
     
  26.  
    loadingView=[[LoadingDataView alloc] initSrollView:table delegate:self];
  27.  
     
  28.  
    [self POST:@"your URL" parameters:nil startBlock:^{
  29.  
    [loadingView startShowView];
  30.  
    } endBlock:^(NSDictionary *response, NSError *error) {
  31.  
    [loadingView endShowView:error responese:response];
  32.  
    }];
  33.  
     
  34.  
    }
  35.  
     
  36.  
     
  37.  
     
  38.  
    -(NSArray *)loadingDataViewBindArrarys:(LoadingDataView *)parent{
  39.  
    return arrList;
  40.  
    }
  41.  
     
  42.  
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
  43.  
     
  44.  
    return [arrList count];
  45.  
    }
  46.  
    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
  47.  
    return 1;
  48.  
    }
  49.  
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
  50.  
    return 44;
  51.  
    }
  52.  
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
  53.  
    return [[UITableViewCell alloc] init];
  54.  
    }
  55.  
    -(void)POST:(NSString *)URLString
  56.  
    parameters:(NSDictionary *)dic
  57.  
    startBlock:(void (^ __nullable)(void))startBlock
  58.  
    endBlock:(void (^ __nullable)(NSDictionary *response,NSError * error))endBlock
  59.  
     
  60.  
    {
  61.  
     
  62.  
    startBlock();
  63.  
     
  64.  
     
  65.  
     
  66.  
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
  67.  
     
  68.  
     
  69.  
     
  70.  
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
  71.  
     
  72.  
     
  73.  
    [manager POST:URLString parameters:dic progress:^(NSProgress * _Nonnull uploadProgress) {
  74.  
     
  75.  
     
  76.  
    } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
  77.  
     
  78.  
    NSDictionary *obj = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
  79.  
     
  80.  
    endBlock(obj,nil);
  81.  
     
  82.  
     
  83.  
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
  84.  
    endBlock(nil,error);
  85.  
     
  86.  
    }];
  87.  
     
  88.  
     
  89.  
     
  90.  
     
  91.  
    }
  92.  
     
  93.  
     
  94.  
     
  95.  
    - (void)didReceiveMemoryWarning {
  96.  
    [super didReceiveMemoryWarning];
  97.  
    // Dispose of any resources that can be recreated.
  98.  
    }

注意:这里的TestViewController 是继承 BaseViewController的

如下:

  1.  
    @interface TestViewController : BaseViewController
  2.  
     
  3.  
    @end

OK ,这就是我的思路。。。

UITableView加载数据,没有数据,没有网络界面处理的更多相关文章

  1. UITableView加载网络数据的优化

    UITableView加载网络数据的优化 效果 源码 https://github.com/YouXianMing/Animations // // TableViewLoadDataControll ...

  2. hive 压缩全解读(hive表存储格式以及外部表直接加载压缩格式数据);HADOOP存储数据压缩方案对比(LZO,gz,ORC)

    数据做压缩和解压缩会增加CPU的开销,但可以最大程度的减少文件所需的磁盘空间和网络I/O的开销,所以最好对那些I/O密集型的作业使用数据压缩,cpu密集型,使用压缩反而会降低性能. 而hive中间结果 ...

  3. HTTP 筛选器 DLL C:\Windows\Microsoft.Net\Framework\v4.0.30319\aspnet_filter.dll 加载失败。数据是错误。

    今天在一台win2003的云主机上,安装.net 4.0时,所有的网站都打不开了.打开事件查看器,发现以下错误: HTTP 筛选器 DLL C:\Windows\Microsoft.Net\Frame ...

  4. [原创.数据可视化系列之三]使用Ol3加载大量点数据

    不管是百度地图还是高德地图,都很难得见到在地图上加载大量点要素,比如同屏1000的,因为这样客户端性能会很低,尤其是IE系列的浏览器,简直是卡的要死.但有的时候,还真的需要,比如,我要加载全球的AQI ...

  5. jsTree 的简单用法--异步加载和刷新数据

    首先这两个文件是必须要引用的,还有就是引用 jQuery 文件就不说了: <link href="/css/plugins/jsTree/style.min.css" rel ...

  6. 使用getJSON()方法异步加载JSON格式数据

    使用getJSON()方法异步加载JSON格式数据 使用getJSON()方法可以通过Ajax异步请求的方式,获取服务器中的数组,并对获取的数据进行解析,显示在页面中,它的调用格式为: jQuery. ...

  7. 异步加载回来的数据不受JS控制了

    写成下面这种方式时,异步加载回来的数据不受JS控制 $(."orderdiv").click(function(){ $(this).find(".orderinfo&q ...

  8. echarts 图表重新加载,原来的数据依然存在图表上

    问题 在做一个全国地图上一些饼图,并且向省一级的地图钻取的时候,原来的饼图依然显示 原因 echars所有添加的图表都在一个series属性集合中,并且同一个echars对象默认是合并之前的数据的,所 ...

  9. mxnet自定义dataloader加载自己的数据

    实际上关于pytorch加载自己的数据之前有写过一篇博客,但是最近接触了mxnet,发现关于这方面的教程很少 如果要加载自己定义的数据的话,看mxnet关于mnist基本上能够推测12 看pytorc ...

随机推荐

  1. Asp.Net WebApi 项目及依赖整理

    一.目前版本 Microsoft ASP.NET Web API 2.2 对应程序集版本5.2.3 二.默认生成的配置文件中的内容 <packages> <package id=&q ...

  2. ugui中toggle.isOn的属性笔记

    准备知识 toggle:指unity3d引擎中UGUI的 toggle组件 (单选框) 本文使用lua语言描述 事件触发 使用unity的ugui,你如果细心观察会发现toggle在界面被关闭/隐藏( ...

  3. python多线程与多进程--存活主机ping扫描以及爬取股票价格

    python多线程与多进程 多线程: 案例:扫描给定网络中存活的主机(通过ping来测试,有响应则说明主机存活) 普通版本: #扫描给定网络中存活的主机(通过ping来测试,有响应则说明主机存活)im ...

  4. MATLAB常微分方程数值解——欧拉法、改进的欧拉法与四阶龙格库塔方法

    MATLAB常微分方程数值解 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1.一阶常微分方程初值问题 2.欧拉法 3.改进的欧拉法 4.四阶龙格库塔 ...

  5. [福大软工] Z班 第2次成绩排行榜

    作业链接 http://www.cnblogs.com/easteast/p/7469291.html 评分细则 本次个人项目分数由三部分组成,分别是 (1)博客 - 20分,分数组成如下: 在文章开 ...

  6. 一文读懂SpringCloud与Eureka,Feign,Ribbon,Hystrix,Zuul核心组件间的关系

    概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术.不过大多数讲解还停留在对Spring Cloud功能使用的层面,其底层的很多原理,很多人可能并不知晓 ...

  7. ubuntu下定时任务的执行

    概述 linux系统由 cron (crond) 这个系统服务来控制例行性计划任务.Linux 系统上面原本就有非常多的计划性工作,因此这个系统服务是默认启动的. 另外, 由于使用者自己也可以设置计划 ...

  8. Python学习之函数进阶

    函数的命名空间 著名的python之禅 Beautiful is better than ugly. Explicit is better than implicit. Simple is bette ...

  9. Java 8 新特性:2-消费者(Consumer)接口

    (原) 在上一篇,用到过这样一个方法: list.forEach(new Consumer<Integer>() { @Override public void accept(Intege ...

  10. 002_监测ssl证书过期时间

    一. s_client This implements a generic SSL/TLS client which can establish a transparent connection to ...