美文网首页技术iOSiOS -- Demo
UITableView没数据时用户提示如何做?

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

作者: 51bitquant | 来源:发表于2015-10-27 18:02 被阅读8593次

前言

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

// 显示无数据提示
- (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

相关文章

网友评论

  • 彼岸等着:关机你们什么都得不到
  • 鬼晓晓:有没有办法显示在偏上呢...
  • 五蕴盛:缺少xcworkSpace 文件
  • koreadragon:我一直有个bug解决不了, label.textAlignment = kCTTextAlignmentCenter;然后文字竟然显示在右边;然后label.textAlignment = kCTTextAlignmentRight;文字显示在屏幕中间,什么鬼
  • 44832370a1f6:有一点瑕疵,就是当第一次加载tableView的时候,这个"没有更多商品也会出现",看着很不爽,有办法去掉吗?
    51bitquant:@EkkoCrystal 通过缓存来处理
  • 灵台无计:感谢楼主的方法,确实很好用,我之前看你写的iOS日历类然后自己写了处理时间的方法,真心感谢
  • Cocos543:直接写个扩展,用backgroundView就可以了.....

    #import <Foundation/Foundation.h>

    @interface UITableView (NetworkStateDisplay)

    - (void)displayOfflineBackgroundView;

    @EnD

    #import "UITableView+NetworkStateDisplay.h"

    @Implementation UITableView (NetworkStateDisplay)


    - (void)displayOfflineBackgroundView {
    UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Offline"]];
    imgView.contentMode = UIViewContentModeCenter;
    [self setBackgroundView:imgView];
    }
    @EnD
  • 7b6c4671d61e:如果我想显示图片,怎么调整图片大小
    7b6c4671d61e:@StephenMark 哇嗷 厉害 今天去看看
    51bitquant:@江方钟 已经上传代码,支持自定义view,可以添加图片等!
  • Jerry在种草:原来是backgroundview呐,挺好的。
  • MrFire_:扩展这个方式真的很不错,之前怎么木有想到尼?赞一个!
    51bitquant:@hungryBoy 已经添加了demo,记得去githubstar
  • 吃你煮的鱼:如果上面加按钮是点击不到的。iOS7下
    51bitquant:@吃你煮的鱼 已经添加demo,支持自定义view
  • a1207b4e82b6:不错的想法
  • 5f542948a211:label的frame:CGRectMake(0, ScreenHeight-150, ScreenWidth, 25)
    添加的位置:[self.view addSubview:_noDataLabel];
    很显然这个label是要显示在View的底部的,只有25高度的一个细条,而你写的这个是全屏幕的,并不是人家上面那些代码实现的需求。。。。
    5f542948a211:人家需求就是在中心,你这个完全不是人家要的需求
    51bitquant:@一人心sadness 同事实现不是在中心,是在偏下位置
  • loverker:@StephenMark 是的我数据源个数实际上是24个,前三次返回0、走了楼主扩展为的类方法,这并不是我想要的结果。请问楼主能不能帮我分析是什么问题
    loverker:@StephenMark 刚才发给你代码的时候服务器出问题了
    loverker:有数据,但是已经走了数据源为0,再走的24
    51bitquant:@loverker 意思是它还显示没有数据是吗?把代码发给我也下吧!发到群里
  • loverker:楼主, 我有一个问题,number of rows 方法会被调多次,我这上面调了四次,前三次数据源的数组个数为0,第四次才返回数组的真正个数,那么你写的扩展方法已经走过了。起不到根本作用,难道是我的数据源刷新出了问题?
    51bitquant:@loverker 这个方法走多次的!看你刷新的方法对不对,tableview初始化的时候也会走一次。刷新的时候也会走
  • 叫我李五:学习了👍🏻
  • Eason_Gao:写扩展的方式确实不错,点个赞
  • syyjay:赞
  • 许还真:原来使用backgroundview
  • 73823c561b0e:赞👍🏻
  • f4d44c07f129:不错,收藏
  • hrscy:不错~
  • iHTCboy:漂亮! 讨论一下:比如是地址列表,如何没有地址,则需要一个按钮提示添加,能通过重写代理方法,定义自己的列表来实现?
    落影loyinglin:@iHTCboy 如果是有交互的 你可以专门做一个没数据的时候用的大cell就行了。
  • Gargit:不错啊,简单,可是效果不错
    51bitquant:@Gargit 越简单越好!维护方便
  • 吊儿郎当的认真:sizetofit有什么用?你没有给label的位置啊
    我的天空蔚蓝色:@e5e7448ac58c 自适应大小的
    51bitquant:@e5e7448ac58c 你先用一下就知道了!不用解释
  • 马海东:求产品总监、运营总监、艺术家服务总监、市场公关总监各一位
    51bitquant:@马海东 贵公司做什么产品呢?
  • Metoo33:好像逻辑不对。。。。TableView分区至少为1、当TableView有多个Section时、[tableView tableViewDisplayWitMsg:@"没有查询到相对应的商品" ifNecessaryForRowCount:self.dataSource.count];肯定不会被执行 代码有问题
    hrscy:是这样,我现在的程序是在一个控制上显示两个tableView,每个tableView都只有1组数据,我把numberOfSectionsInTableView:和tableView: numberOfRowsInSection:中内容颠倒了,可以正常运行,没有问题,如果是多个section的话用不用颠倒两个方法里的内容了,感谢楼主分享~ :smile:
    Metoo33:@StephenMark 明白。。。谢谢你的分享
    51bitquant:@Metoo33 看你的数据源是怎么样?要section还是用row来判断
  • wwwbbat:DZNEmptyDataSet 你所做的已经有人做了。
    51bitquant:@nbhhcty 已经添加demo,支持自定义view,可以去github看看,
    nbhhcty:@StephenMark 已经有人做了,又怎么了?分享给更多的人知道,才好!楼主加油,让更多的人看到你更多优秀的作品 :+1:
    51bitquant:@Voyager3 这个只是一个小技巧,用工具类,写个方法在控制器都可以实现,只是怎么做比较方便,对于代码的扩展比较好罢了
  • 奔跑的码农:确实比较的好的解决的方案 之前都是谢了个公共类去解决的 老是觉得用起来比较的复杂!这样写代码简洁 延展性比较强!替作者点个赞~~~
    51bitquant:@奔跑的码农 谢谢你的赞赏
  • 十一岁的加重:有意思,多写点这种技巧出来吧
    51bitquant:@十一岁的加重 多多交流
  • zhq1992:楼主 我是iOS新手,我直接在控制器里写添加scrollView的方法 ,这样是不是也不合理
    51bitquant:@宁波iOS 尽可能不要让控制器处理多的业务逻辑
  • zhq1992:厉害

本文标题:UITableView没数据时用户提示如何做?

本文链接:https://www.haomeiwen.com/subject/ncvxhttx.html