美文网首页
当TableView没有数据源时,如何显示占位图片?

当TableView没有数据源时,如何显示占位图片?

作者: I_YoYo | 来源:发表于2017-08-26 22:58 被阅读75次

    有时候项目中有这样的需求,页面包含一个UITableVeiw,当没有数据的时候显示一张占位图片,点击图片可以重新刷新数据。效果图如下:


    有数据时.png
    没数据时.png

    思路

    为UITableView增加个Category,利用方法method_exchangeImplementations交换reloadData方法为real_ReloadData,在real_ReloadData方法内判断是否有数据源,再动态显示占位的UIView。
    在创建UITableView的地方一句代码设置占位控件。
        tableView.placeHolderView = [[PlaceholderView alloc]initWithFrame:tableView.bounds onTapView:^{
          //点击占位图片
        }];
        [self.view addSubview:tableView];
    

    UITableView+Placeholder.h文件

    #import <UIKit/UIKit.h>
    @interface UITableView (Placeholder)
    /* 占位图 */
    @property (nonatomic, strong) UIView *placeHolderView;
    @end
    

    UITableView+Placeholder.m文件

    #import "UITableView+Placeholder.h"
    #import <objc/runtime.h>
    
    @implementation UITableView (Placeholder)
    
    + (void)load
    {
        //交换刷新方法
        Method reloadData =class_getInstanceMethod(self,  @selector(reloadData));
        Method real_ReloadData =class_getInstanceMethod(self, @selector(real_ReloadData));
        method_exchangeImplementations(reloadData, real_ReloadData);
    }
    
    -(void)real_ReloadData
    {
        [self dataIsEmpty];
        [self real_ReloadData];
    }
    
    /** 判断是否有数据源,没有数据源则显示占位图片  */
    - (void)dataIsEmpty
    {
        BOOL isEmpty = YES;
        id<UITableViewDataSource> dataSourse = self.dataSource;
        //检测是否有数据源
        if ([dataSourse respondsToSelector:@selector(numberOfSectionsInTableView:)]) {//group
            NSInteger sections = [dataSourse numberOfSectionsInTableView:self];
            if (sections >0) {
                isEmpty = NO;
            }
        }else if([dataSourse respondsToSelector:@selector(tableView:numberOfRowsInSection:)]){//plain
            NSInteger rows = [dataSourse tableView:self numberOfRowsInSection:0];
            if (rows >0) {
                isEmpty = NO;
            }
        }
        if (isEmpty) {//显示占位图
            [self.placeHolderView removeFromSuperview];
            [self addSubview:self.placeHolderView];
        }else{//移除占位图片
            [self.placeHolderView removeFromSuperview];
        }
    }
    - (void)setPlaceHolderView:(UIView *)placeHolderView
    {
        objc_setAssociatedObject(self, @selector(placeHolderView), placeHolderView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (UIView *)placeHolderView
    {
        return objc_getAssociatedObject(self, @selector(placeHolderView));
    }
    
    
    自定义占位的UIView 为PlaceholderView

    PlaceholderView.h文件

    #import <UIKit/UIKit.h>
    //点击后的回调
    typedef void(^TapBlock)();
    @interface PlaceholderView : UIView
    @property(nonatomic,copy)TapBlock onTapBlock;
    - (instancetype)initWithFrame:(CGRect)frame onTapView:(TapBlock)onTapBlock;
    @end
    

    PlaceholderView.m文件

    #import "PlaceholderView.h"
    
    @implementation PlaceholderView
    {
        UIImageView *_imageView;
    }
    
    - (instancetype)initWithFrame:(CGRect)frame onTapView:(TapBlock)onTapBlock
    {
        self = [super initWithFrame:frame];
        if (self) {
            self.backgroundColor = [UIColor whiteColor];
            self.onTapBlock = onTapBlock;
            [self setupSubViews];
        }
        return self;
    }
    -(void)setupSubViews
    {
        UIImageView *imageView =[[UIImageView alloc]init];
        imageView.userInteractionEnabled = YES;
        imageView.contentMode = UIViewContentModeCenter;
        [imageView setImage:[UIImage imageNamed:@"nodataPlaceholder"]];
        _imageView = imageView;
        [self addSubview:imageView];
        
        [self addGestureRecognizer:[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(onTapView:)]];
    }
    -(void)layoutSubviews
    {
        [super layoutSubviews];
        _imageView.frame = self.bounds;
    }
    /** 增加点击手势 **/
    -(void)onTapView:(UITapGestureRecognizer *)recognizer
    {
        if (self.onTapBlock) {
            self.onTapBlock();
        }
    }
    

    这样当这个需求发生变化时,改动相对来说更小。当然,还可以把设置placeholderView的代码也封装到UItableView分类的init里面去。
    点击下载Demo 有什么错误欢迎批评指正 。

    相关文章

      网友评论

          本文标题:当TableView没有数据源时,如何显示占位图片?

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