iOS开发者iOS学习开发傲视苍穹iOS《Objective-C》VIP专题

UITableView实现无数据占位图片

2017-07-25  本文已影响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

上一篇下一篇

猜你喜欢

热点阅读