UITableView实现无数据占位图片

作者: 搬运工开发者 | 来源:发表于2017-07-25 15:44 被阅读285次

    国际惯例,上效果图


    1.gif

    该效果的实现主要是使用runtime的交叉方法实现,将tableView的reloadData与自定义的kk_reloadData交换。新建tableView的Category。
    交换方法主要代码

    + (void)swizzleInstanceSelector:(SEL)originalSel
               WithSwizzledSelector:(SEL)swizzledSel {
        
        Method originMethod = class_getInstanceMethod(self, originalSel);
        Method swizzedMehtod = class_getInstanceMethod(self, swizzledSel);
        BOOL methodAdded = class_addMethod(self, originalSel, method_getImplementation(swizzedMehtod), method_getTypeEncoding(swizzedMehtod));
        
        if (methodAdded) {
            class_replaceMethod(self, swizzledSel, method_getImplementation(originMethod), method_getTypeEncoding(originMethod));
        }else{
            method_exchangeImplementations(originMethod, swizzedMehtod);
        }
    }
    

    交换reloadData

    + (void)load {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            [self swizzleInstanceSelector:@selector(reloadData) WithSwizzledSelector:@selector(kk_reloadData)];
        });
    }
    

    kk_reloadData方法,先检查是否有数据,再次kk_reloadData方法此时已使用runtime的交换方法则则实际上调用的是系统的reloadData方法。

    - (void)kk_reloadData {
        [self kk_checkEmpty];
        [self kk_reloadData];
    }
    

    kk_checkEmpty方法

    - (void)kk_checkEmpty {
       BOOL isEmpty = YES;
       id<UITableViewDataSource> src = self.dataSource;
       NSInteger sections = 1;
       if ([src respondsToSelector:@selector(numberOfSectionsInTableView:)]) {
           sections = [src numberOfSectionsInTableView:self];
       }
       for (int i = 0; i < sections; i++) {
           NSInteger rows = [src tableView:self numberOfRowsInSection:i];
           if (rows) {
               isEmpty = NO;
           }
       }
       if (isEmpty) {//数据为空,在这里添加视图
       }else{//数据不为空,在这里一处视图
       }
    }
    

    为了降低代码的侵入,可以给tableView动态添加一个View属性即是占位图视图。

    @property (nonatomic, strong) UIView *placeHolderView;
    
    - (void)setPlaceHolderView:(UIView *)placeHolderView {
        objc_setAssociatedObject(self, @selector(placeHolderView), placeHolderView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    - (UIView *)placeHolderView {
        return objc_getAssociatedObject(self, @selector(placeHolderView));
    }
    

    kk_checkEmpty的

    if (isEmpty) {//数据为空,在这里添加视图
    }else{//数据不为空,在这里一处视图
    }
    

    修改为

        if (isEmpty) {
            [self.placeHolderView removeFromSuperview];
            [self addSubview:self.placeHolderView];
        }else{
            [self.placeHolderView removeFromSuperview];
        }
    

    以后使用的时候只需设置tableView的placeHolderView属性即可

     _tableView.placeHolderView = [[UIView alloc] init];
    

    打完收工
    github地址:https://github.com/wuzaozhou/UITableView-placeholder

    相关文章

      网友评论

        本文标题:UITableView实现无数据占位图片

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