DZNEmptyDataSet源碼

DZNEmptyDataSet是一款優(yōu)秀的處理數據集合為空的輕量型框架

基于 UITableView/UICollectionView 的category類,默認情況下,如果我們的的表視圖是空的,屏幕上什么也不會顯示,它給用戶的體驗不是很好。該庫可以很靈活地幫我們很好地處理集合視圖,然后合理美觀地顯示出用戶信息。

1,用法

使用的方法還是很簡單, 下載官方的demo一看懂了,快捷方便,設置相應代理即可

    self.tableView.emptyDataSetSource = self;
    self.tableView.emptyDataSetDelegate = self;

然后再根據具體的需要自定義自己App的顯示特點,DZNEmptyDataSet為我們提供了豐富多種的設置方法,其中常用的方法有3個


/**
  數據為空時,顯示的提示標語
 */
- (nullable NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView;

/**
  數據為空時,顯示的提示顯示內容
 */
- (nullable NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView;

/**
  數據為空時,顯示的提示顯示圖像
 */
- (nullable UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView;

2,實現(xiàn)原理

關鍵的意思就運用了runtime特性,替換掉UITableView 或者 UICollectionView 的reloadData 函數

    // Swizzle by injecting additional implementation
    Method method = class_getInstanceMethod(baseClass, selector);
    IMP dzn_newImplementation = method_setImplementation(method, (IMP)dzn_original_implementation);

攔截該方法之后在適當的時機計算datasource的數量,如果總數量為空就像是相應的視圖,否則還是按照原本的處理邏輯

- (NSInteger)dzn_itemsCount
{
    NSInteger items = 0;
    
    // UIScollView doesn't respond to 'dataSource' so let's exit
    if (![self respondsToSelector:@selector(dataSource)]) {
        return items;
    }
    
    // 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];
            }
        }
    }
    
    return items;
}

3,我也嘗試寫過類似控件

實現(xiàn)的思路和DZNEmptyDataSet思路基本是一致
1,添加分類
2,運行時攔截替換reloadata函數
3,計算datasource數量,作相應處理。

發(fā)現(xiàn)了DZNEmptyDataSet 幾個地方可優(yōu)化的地方
1,headerView顯示過長的時候可以自動適當調節(jié)EmptyView的frame
2,網絡狀態(tài)異常可以自動顯示文本提示,不用額外添加代碼處理。
3,需要額外設置其delegate和datasource方能生效。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容