1. 程式人生 > >[iOS]一行程式碼整合空白頁面佔位圖(基於runtime+MJRefresh思想)

[iOS]一行程式碼整合空白頁面佔位圖(基於runtime+MJRefresh思想)

LYEmptyView

此框架是本人在5,6個月前,公司啟動新專案的時候,一起開始著手編寫的,經過這個專案的驗證與考驗,不斷的進行完善,在此特將這份框架分享出來供大家參考與學習。
github地址:https://github.com/yangli-dev/LYEmptyView

不需要遵循協議,不需要設定代理,不需要實現代理方法,只需這一句程式碼,就可為一個UITableViwe/UICollectionView整合空白頁面佔位圖。self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];

目錄

  • 一 效果展示
  • 二 使用參考示例
        * 1 一行程式碼整合空內容檢視
        * 2 自由選擇空內容元素
        * 3 自定義空內容元素
        * 4 自定義元素的UI樣式
        * 5 二次封裝
        * 6 延遲顯示emptyView
        * 7 特殊需求,手動控制emptyView的顯示隱藏

一 效果展示

show.gif

ImitateOtherApp.png

二 使用參考示例

1 一行程式碼整合空內容檢視

//框架方法
self.tableView.ly_emptyView = [LYEmptyView emptyViewWithImageStr:@"noData"
                                                        titleStr:@"暫無資料,點選重新載入"
                                                       detailStr:@""];

PS:可對框架進行二次封裝,呼叫更簡潔(二次封裝方法在下面的示例5中會講到)

//二次封裝方法,呼叫簡潔
self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];

完全低耦合,在你的專案中加入這一行程式碼就可整合
不管專案中是reloadData方法刷UI還是insert、delete等方式刷UI,不需做其他任何操作,只需這一行程式碼就可實現以下效果

example1.gif

2 自由選擇空內容元素

互動事件可選擇SEL或block方式
SEL互動事件:
self.tableView.ly_emptyView = [LYEmptyView emptyActionViewWithImageStr:@"noData"
titleStr:@"無資料" detailStr:@"請稍後再試!" btnTitleStr:@"重新載入" target:target action:action];
block互動事件: self.tableView.ly_emptyView = [LYEmptyView emptyActionViewWithImageStr:@"noData" titleStr:@"" detailStr:@"" btnTitleStr:@"" btnClickBlock:^{}]; // imageStr   : 佔位圖片 // titleStr   : 標題 // detailStr   : 詳細描述 // btnTitleStr : 按鈕標題

框架提供四個元素,傳入相應元素的字串即可顯示對應元素(按鈕的顯示前提是傳入target,action或btnClickBlock)
可根據專案需求,自由進行組合,如下只展示了部分組合效果

example2.png

3 自定義空內容元素

特殊情況下,如果空內容狀態佈局不滿足需求時,可進行自定義
通過方法+ (instancetype)emptyViewWithCustomView:(UIView *)customView;
傳入一個View 即可建立一個自定義的emptyView

self.tableView.ly_emptyView = [LYEmptyView emptyViewWithCustomView:customView];

example3.png

4 自定義元素的UI樣式

這裡自定義UI樣式需要很多程式碼,別擔心,在示例5中會講解二次封裝的方式,封裝後呼叫時就只需要一行程式碼了 ^ _ ^

  //初始化一個emptyView
  LYEmptyView *emptyView = [LYEmptyView emptyActionViewWithImageStr:@"noData"
                                                           titleStr:@"無資料"
                                                          detailStr:@"請稍後再試!"
                                                        btnTitleStr:@"重新載入"
                                                      btnClickBlock:^{}];
  //元素豎直方向的間距
  emptyView.subViewMargin = 20.f;
  //標題顏色
  emptyView.titleLabTextColor = MainColor(90, 180, 160);
  //描述顏色
  emptyView.detailLabTextColor = MainColor(180, 120, 90);
  //按鈕背景色
  emptyView.actionBtnBackGroundColor = MainColor(90, 180, 160);

  //設定空內容佔位圖
  self.tableView.ly_emptyView = emptyView;

這裡只列舉了一些常用的屬性,更多屬性請到LYEmptyView.h檢視

example4.png

5 二次封裝

第4小節的示例程式碼,修改emptyView的樣式需要一個個屬性單獨去改,如果專案中每個介面都這麼寫就顯得很麻煩,而且不易維護
解決辦法是對庫進行二次封裝,二次封裝後,對UI樣式單獨管理,方便維護

1)新建一個類繼承自LYEmptyView,例如demo中的MyDIYEmpty
2)重寫- (void)prepare 方法,並修改想要改變的元素的UI樣式
- (void)prepare{
    [super prepare];

    self.titleLabFont = [UIFont systemFontOfSize:25];
    self.titleLabTextColor = MainColor(90, 180, 160);

    self.detailLabFont = [UIFont systemFontOfSize:17];
    self.detailLabTextColor = MainColor(180, 120, 90);
    self.detailLabMaxLines = 5;

    self.actionBtnBackGroundColor = MainColor(90, 180, 160);
    self.actionBtnTitleColor = [UIColor whiteColor];
}

操作上面的兩步就可實現對樣式的單獨管理
呼叫方法不變,只是呼叫的類變成了MYDiyEmpty

self.tableView.ly_emptyView = [MYDiyEmpty emptyActionViewWithImageStr:@"noData"
                                                             titleStr:@"暫無資料"
                                                            detailStr:@"請稍後再試!"
                                                          btnTitleStr:@"重新載入"
                                                        btnClickBlock:^{}];
3)進一步封裝顯示的元素內容,比如無資料狀態圖、無網路狀態圖

在MYDiyEmpty.h定義方法+ (instancetype)diyNoDataEmpty;
在MYDiyEmpty.m實現方法

+ (instancetype)diyNoDataEmpty{
    return [MyDIYEmpty emptyViewWithImageStr:@"noData"
                                    titleStr:@"暫無資料"
                                   detailStr:@"請稍後再試!"];
}

經過3步封裝,自定義了UI樣式,使管理更方便,使呼叫更簡潔
self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];

下面的兩種示例,屬於特殊需求,需要四行程式碼搞定,呼叫和MJRefrsh類似,需要先設定樣式,然後顯示和隱藏

6 延遲顯示emptyView

如示例1圖,框架自動根據DataSource計算是否顯示emptyView,在空頁面發起網路請求時,DataSource肯定為空,會自動顯示emptyView,有的產品需求可能不希望這樣,希望發起請求時暫時隱藏emptyView。
本框架提供了兩個方法可實現此需求,兩個方法都是scrollView的分類,呼叫非常方便

 /**
   一般用於開始請求網路時呼叫,ly_startLoading呼叫時會暫時隱藏emptyView
   當呼叫ly_endLoading方法時,ly_endLoading方法內部會根據當前的tableView/collectionView的
   DataSource來自動判斷是否顯示emptyView
 */
- (void)ly_startLoading;

 /**
   在想要重新整理emptyView狀態時呼叫
   注意:ly_endLoading 的呼叫時機,有重新整理UI的地方一定要等到重新整理UI的方法之後呼叫,
   因為只有重新整理了UI,view的DataSource才會更新,故呼叫此方法才能正確判斷是否有內容。
 */
- (void)ly_endLoading;

*注意點:使用這兩個方法,請先將emptyView的autoShowEmptyView屬性置為NO,關閉自動顯隱

以下是呼叫示例(具體細節可參考demo中的demo2)

//1.先設定樣式
self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];
//2.關閉自動顯隱(此步可封裝進自定義類中,相關呼叫就可省去這步)
self.tableView.ly_emptyView.autoShowEmptyView = NO;
//3.網路請求時呼叫
[self.tableView ly_startLoading];
//4.重新整理UI時呼叫(保證在重新整理UI後呼叫)
[self.tableView ly_endLoading];

example6.gif

7 特殊需求,手動控制emptyView的顯示隱藏

在某些特殊介面下,有的tableView/collectionView有固定的一些死資料,其它的資料根據網路載入,這時根據以上的示例方法可能達不到這需求。
本框架提供另外的兩個方法來解決這個問題。

/**
 手動呼叫顯示emptyView
 */
- (void)ly_showEmptyView;

/**
 手動呼叫隱藏emptyView
 */
- (void)ly_hideEmptyView;

*注意點:使用這兩個方法,請先將emptyView的autoShowEmptyView屬性置為NO,關閉自動顯隱

以下是呼叫示例(具體細節可參考demo中的demo4)

//1.先設定樣式
self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];
//2.關閉自動顯隱(此步可封裝進自定義類中,相關呼叫就可省去這步)
self.tableView.ly_emptyView.autoShowEmptyView = NO;
//3.顯示emptyView
[self.tableView ly_showEmptyView];
//4.隱藏emptyView
[self.tableView ly_hideEmptyView];

example7.gif