zoukankan      html  css  js  c++  java
  • UITableView加载数据,没有数据,没有网络界面处理

    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 ,这就是我的思路。。。

  • 相关阅读:
    MySQL索引的操作
    MySQL表的操作02
    MySQL表的操作01
    字典实现简单购物车程序
    python 中if和elif的区别
    格式化操作---%方法
    正则表达式相关知识
    实现 像网易云音乐 播放列表那样的弹出型Dialog
    为什么在非UI线程中操作UI的改变失不安全的
    模板方法模式-Template Method
  • 原文地址:https://www.cnblogs.com/sundaysgarden/p/9453463.html
Copyright © 2011-2022 走看看