UITableView加载数据,没有数据,没有网络界面处理


俗话说的好,傻逼的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里面当然是用代理了


@protocol LoadingDataViewDelegate <NSObject>

@required
-(nullable UIView *)loadingDataViewWithNodata:(nullable LoadingDataView *)parent ;
@required
-(nullable UIView *)loadingDataViewWithNoNet:(nullable LoadingDataView *)parent ;
@required
-(nullable UIView *)loadingDataViewWithLoading:(nullable LoadingDataView *)parent ;

@required
-(nullable NSArray *)loadingDataViewBindArrarys:(nullable LoadingDataView *)parent;

@end




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

@interface LoadingDataView : UIView

-(nullable id)initSrollView:(nullable UIScrollView *)scrollView delegate:(id<LoadingDataViewDelegate>)delegate;

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

-(void)startShowView;
-(void)endShowView:(NSError *)error responese:(id)response;

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

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

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

@implementation LoadingDataView{
    
    
    UIView *noDataView;
    UIView *noNetView;
    UIView *loadingView;
    NSArray *arrList;
    
    
}


-(nullable id)initSrollView:(nullable UIScrollView *)scrollView delegate:(id<LoadingDataViewDelegate>)delegate{
    
    if (self=[super init]) {
        self.delegate=delegate;
        
        
        arrList=[delegate loadingDataViewBindArrarys:self];
        
        self.frame=CGRectMake(0, 0, scrollView.frame.size.width, scrollView.frame.size.height);
        
        noDataView=[delegate loadingDataViewWithNodata:self ];
        noNetView=[delegate loadingDataViewWithNoNet:self ];
        loadingView=[delegate loadingDataViewWithLoading:self ];
        
        [self addSubview:noDataView];
        [self addSubview:noNetView];
        [self addSubview:loadingView];
        
        [self showLoadingView];
        
        
    }
    
    
    [scrollView addSubview:self];
    
    return  self;
    
    
    
}


-(void)showLoadingView{
    self.hidden=NO;
    loadingView.hidden=NO;
    noNetView.hidden=YES;
    noDataView.hidden=YES;
}

-(void)showNoNetView{
    self.hidden=NO;
    loadingView.hidden=YES;
    noNetView.hidden=NO;
    noDataView.hidden=YES;
}
-(void)showNoDataView{
    self.hidden=NO;
    loadingView.hidden=YES;
    noNetView.hidden=YES;
    noDataView.hidden=NO;
}

-(void)showNormalView{
    self.hidden=YES;
     
}

-(void)startShowView{
    
    
    if (arrList.count==0) {
        [self showLoadingView];
    }else{
        [self showNoNetView];
    }
    
}

-(void)endShowView:(NSError *)error responese:(id)response{
    if (error==nil) {
        
            if ([arrList count]==0) {
                [self showNoDataView];
            }else{
                [self showNormalView];
            }
       
        
    }else{
        
            if ([arrList count]==0) {
                [self showNoNetView];
            }else{
                [self showNormalView];
            }
    }

    
}
-(nullable NSArray *)loadingDataViewBindArrarys:(nullable LoadingDataView *)parent{
    
    return [self.delegate loadingDataViewBindArrarys:parent];
    
}

-(UIView *)nodataView:(LoadingDataView *)parent  {
    
    return [self.delegate loadingDataViewWithNoNet:parent];
}
-(UIView *)nonetView:(LoadingDataView *)parent  {
    
    
    return [self.delegate loadingDataViewWithNoNet:parent];
}
-(UIView *)loadingView:(LoadingDataView *)parent  {
    
    return [self.delegate loadingDataViewWithLoading:parent];
}

@end


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

#import <UIKit/UIKit.h>
#import "LoadingDataViewDelegate.h"

@interface BaseViewController : UIViewController<LoadingDataViewDelegate>

@end


并重写代理方法

#import "BaseViewController.h"



@interface BaseViewController ()

@end

@implementation BaseViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    
}
-(nullable NSArray *)loadingDataViewBindArrarys:(nullable LoadingDataView *)parent{
    
    
    return nil;
    
}


-(UIView *)loadingDataViewWithNoNet:(LoadingDataView *)parent{
    
    
    UIView *vi=[[UIView alloc] init];
    vi.frame=CGRectMake(0, 0, parent.frame.size.width, parent.frame.size.height);
    vi.backgroundColor=[UIColor cyanColor];
    
    return vi;
}



-(UIView *)loadingDataViewWithNodata:(LoadingDataView *)parent{
    
    UIView *vi=[[UIView alloc] init];
    vi.frame=CGRectMake(0, 0, parent.frame.size.width, parent.frame.size.height);
    vi.backgroundColor=[UIColor redColor];
    return vi;
    
    
}
-(UIView *)loadingDataViewWithLoading:(LoadingDataView *)parent{
    
    UIView *vi=[[UIView alloc] init];
    vi.frame=CGRectMake(0, 0, parent.frame.size.width, parent.frame.size.height);
    vi.backgroundColor=[UIColor yellowColor];
    return vi;
    
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

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

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

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

源码如下

@interface TestViewController ()<UITableViewDataSource,UITableViewDelegate>{
    
    UITableView *table;
    
    LoadingDataView *loadingView;
    NSMutableArray *arrList;
    
    
    
}

@end

@implementation TestViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    arrList=[[NSMutableArray alloc] init];
    // Do any additional setup after loading the view.
    table=[[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)];
    table.delegate=self;
    table.dataSource=self;
    [self.view addSubview:table];
    
    loadingView=[[LoadingDataView alloc] initSrollView:table delegate:self];
    
    [self POST:@"your URL" parameters:nil startBlock:^{
        [loadingView startShowView];
    } endBlock:^(NSDictionary *response, NSError *error) {
        [loadingView endShowView:error responese:response];
    }];
    
}



-(NSArray *)loadingDataViewBindArrarys:(LoadingDataView *)parent{
    return arrList;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    
    return [arrList count];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 44;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    return [[UITableViewCell alloc] init];
}
-(void)POST:(NSString *)URLString
  parameters:(NSDictionary *)dic
  startBlock:(void (^ __nullable)(void))startBlock
    endBlock:(void (^ __nullable)(NSDictionary *response,NSError * error))endBlock

{
    
    startBlock();
    
    
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    
    
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
    
    [manager POST:URLString parameters:dic progress:^(NSProgress * _Nonnull uploadProgress) {
        
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        NSDictionary *obj = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
        
        endBlock(obj,nil);
        
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        endBlock(nil,error);
        
    }];
    
    
    
    
}



- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


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

如下: 

@interface TestViewController : BaseViewController

@end

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












  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值