UITableView没数据时用户提示如何做?

前言

最近项目在大改,把之前很多的业务功能进行修改。在看到之前同事的代码时,他在处理在网络请求不到数据的时候,提示用户没有数据的代码太不合理。先来看看他的代码。

// 显示无数据提示
- (void)showNoDataLabel
{
    if (!_noDataLabel) {
        _noDataLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, ScreenHeight-150, ScreenWidth, 25)];
        _noDataLabel.text = @"没有查询到相对应的商品";
        _noDataLabel.textColor = COLOR_f15899;
        _noDataLabel.textAlignment = NSTextAlignmentCenter;
        [self.view addSubview:_noDataLabel];
    }
    if ([self.dataSource count] == 0) {
        _noDataLabel.hidden = NO;
    }
    else{
        _noDataLabel.hidden = YES;
    }
}

以上代码是同事他在控制器里面定义一个UILabel属性_noDataLabel,把它添加在控制器的View上,默认这个_noDataLabel是隐藏的。每次在网络请求完成的时候,就调用上面的方法,这个方法会判断数据源数组中有没有数据,如果没有数据,那么_noDataLabel就会显示,如果有数据该_noDataLabel就继续隐藏。这样做当然没有问题,但是这样做很不合理:

  1. 这是一种典型的面向过程的方法,没有进行封装,不便于维护
  2. 这样的代码没有重复利用,所用到的地方,几乎都是要拷贝一份。
  3. 没有很好的利用Objective C这门编程语言的特性-分类。
  4. 导致控制器的代码过多,不便于维护,MVC设计模式变成了Massive ViewController。

解决方法

那么我是怎么做的呢?利用Objective C 的分类可以达到很好的效果,实际上苹果公司的开发也是大量采用分类来做的。之前做HomeKit智能家居开发的时候,看了很多HomeKit的开发文档和HomeKit的demo,其中苹果的Demo很多地方都是利用Catergory来做的。

做法如下:我们对UITabelView进行扩展,代码如下。

// .h文件
@import UIKit;

@interface UITableView (EmptyData)
//添加一个方法
- (void) tableViewDisplayWitMsg:(NSString *) message ifNecessaryForRowCount:(NSUInteger) rowCount;

@end


/// .m文件
#import "UITableView+EmptyData.h"

@implementation UITableView (EmptyData)

- (void) tableViewDisplayWitMsg:(NSString *) message ifNecessaryForRowCount:(NSUInteger) rowCount
{
    if (rowCount == 0) {
        // Display a message when the table is empty
        // 没有数据的时候,UILabel的显示样式
        UILabel *messageLabel = [UILabel new];
        
        messageLabel.text = message;
        messageLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
        messageLabel.textColor = [UIColor lightGrayColor];
        messageLabel.textAlignment = NSTextAlignmentCenter;
        [messageLabel sizeToFit];
        
        self.backgroundView = messageLabel;
        self.separatorStyle = UITableViewCellSeparatorStyleNone;
    } else {
        self.backgroundView = nil;
        self.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    }
}


@end

如何使用

首先导入头文件

> #import "UITableView+EmptyData.h"

UITableView的数据源方法中进行调用就可以了。如果你的TableView有多个Section,那么可以在*- (NSInteger)numberOfSectionsInTableView:(UITableView )tableView方法中进行调用。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    /**
     *  如果没有数据的时候提示用户的信息
     */
    [tableView tableViewDisplayWitMsg:@"没有查询到相对应的商品" ifNecessaryForRowCount:self.dataSource.count];
    return [self.dataSource count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

如果你的TableView只有一个分组,那么可以在**- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section **中进行调用

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    [tableView tableViewDisplayWitMsg:@"没有查询到相对应的商品" ifNecessaryForRowCount:self.dataSource.count];
    return self.dataSource.count;
}

效果如下:

Simulator Screen Shot 2015年10月27日 下午3.27.26.png

只要你的用得到地方,直接导入UITableView的分类就可以了。这样做是不是很方便呢?
代码写多了,是不是要考虑偷懒一下呢?直接复制粘贴,这种简单粗暴的活是不是应该留给年轻人干呢?

demo地址:https://github.com/ramoslin02/WLPlaceHolder

技术交流QQ群:344914307

推荐阅读更多精彩内容