iOS自定义控件:自定义TableView、CollectionView空数据占位图

镇楼图.jpg

最近由于业务需求,需要封装这样的一个提示页面。看了网上方法感觉都大同小异,其中DZNEmptyDataSet是很好的一个库,但是对我个人而言有点大财小用了。所以就借鉴一下其方法,自己封装一个。感觉有更高的自定义性吧。(我是初学者,请大佬爱护,勿喷)
一、封装代码:利用UIScrollView的分类实现

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UIScrollView (WD_NoData)
// 需要显示的占位页面
@property (nonatomic, strong) UIView *noDataView;

@end

NS_ASSUME_NONNULL_END

实现代码

#import "UIScrollView+WD_NoData.h"
#import <objc/runtime.h>

static char *noDataViewKey = "noDataViewKey";

@implementation UIScrollView (WD_NoData)

/**
 交换方法

 @param sel1 原方法
 @param sel2 自定义方法
 @param cls 类
 */
void exchangeSelector(SEL sel1, SEL sel2, Class cls) {
    Class class = [cls class];
    Method originalMethod = class_getInstanceMethod(class, sel1);
    Method swizzledMethod = class_getInstanceMethod(class, sel2);
    BOOL success = class_addMethod(class, sel1, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
    if (success) {
        class_replaceMethod(class, sel2, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

#pragma mark =============== Setter ===============
- (void)setNoDataView:(UIView *)noDataView {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        exchangeSelector(@selector(reloadData), @selector(wd_reloadData), [self class]);
    });
    
    objc_setAssociatedObject(self, noDataViewKey, noDataView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

#pragma mark =============== Getter ===============
- (UIView *)noDataView {
    UIView *noDataView = objc_getAssociatedObject(self, noDataViewKey);
    noDataView.frame = self.frame;
    return noDataView;
}


- (void)wd_reloadData {
    [self wd_reloadData];
    [self wd_checkData];
}

#pragma mark =============== 获取数据 ===============
- (void)wd_checkData {
    NSInteger items = 0;
    
    if (![self respondsToSelector:@selector(dataSource)]) {
        return;
    }
    
    // UITableView support
    if ([self isKindOfClass:[UITableView class]]) {
        
        UITableView *tableView = (UITableView *)self;
        id <UITableViewDataSource> dataSource = tableView.dataSource;
        
        NSInteger sections = 1;
        
        if (dataSource && [dataSource respondsToSelector:@selector(numberOfSectionsInTableView:)]) {
            sections = [dataSource numberOfSectionsInTableView:tableView];
        }
        
        if (dataSource && [dataSource respondsToSelector:@selector(tableView:numberOfRowsInSection:)]) {
            for (NSInteger section = 0; section < sections; section++) {
                items += [dataSource tableView:tableView numberOfRowsInSection:section];
            }
        }
    }
    // UICollectionView support
    else if ([self isKindOfClass:[UICollectionView class]]) {
        
        UICollectionView *collectionView = (UICollectionView *)self;
        id <UICollectionViewDataSource> dataSource = collectionView.dataSource;
        
        NSInteger sections = 1;
        
        if (dataSource && [dataSource respondsToSelector:@selector(numberOfSectionsInCollectionView:)]) {
            sections = [dataSource numberOfSectionsInCollectionView:collectionView];
        }
        
        if (dataSource && [dataSource respondsToSelector:@selector(collectionView:numberOfItemsInSection:)]) {
            for (NSInteger section = 0; section < sections; section++) {
                items += [dataSource collectionView:collectionView numberOfItemsInSection:section];
            }
        }
    }
    
    if ( items == 0 ) {
        [self.superview addSubview:self.noDataView];
    } else {
        [self.noDataView removeFromSuperview];
    }
}
@end

二、使用方法

#import "UIScrollView+WD_NoData.h"
// 自定义页面
#import "WDTestEmptyView.h"
//示例的视图
 WDTestEmptyView *view = [NSBundle.mainBundle loadNibNamed:@"WDTestEmptyView" owner:self options:nil].firstObject;
// 设置视图
self.tableView.noDataView = view;

三、效果图


效果图.gif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 如果说产品经理是生孩子,那么产品运营就是养孩子,同样自己的孩子养的阶段也非常重要,要懂得运营的核心以及分类、运营活...
    明月之眸阅读 750评论 0 6
  • 文/青松 大沙河 记得孩提时 就已娶你进门 可直到今天 才能安心躺下 枕你入眠 交给你呼吸的声音 摩挲着我皱纹的沟...
    济南青松阅读 317评论 0 3
  • 【0430今日话题】小灶群里,你最想采访谁?为什么?最想采访叶波 ,很喜欢摄影,但水平渣,前年也买了一部相机(6D...
    焦距说阅读 559评论 9 3