1.前言
在UITableView(或UICollectionView)無數(shù)據(jù)時我們希望展示一個無數(shù)據(jù)頁面(圖片或文字,還有可能加個按鈕),而不是空空的什么都沒有,最終我們的展示效果如下圖:
2.思路
思路1:在TableView上加個界面,根據(jù)數(shù)據(jù)有無判斷是否展示
實現(xiàn): 沒有數(shù)據(jù)時展示無數(shù)據(jù)界面,首先想到的是在這個界面上寫個無數(shù)據(jù)界面,當(dāng)無數(shù)據(jù)時我們把他展示出來,有數(shù)據(jù)時把他隱藏。
缺點:這樣操作太復(fù)雜,首先在每個需要展示的tableView界面都要添加一個無數(shù)據(jù)界面,然后在請求數(shù)據(jù)后判斷是否有數(shù)據(jù),有數(shù)據(jù)的話隱藏此界面,無數(shù)據(jù)的話展示此界面。
結(jié)果:雖然特別好理解,但是我們不使用這種方法
思路2: 利用KVO,根據(jù)TableView的ContentSize控制界面的展示或隱藏
實現(xiàn):因為tableView繼承自scrollView,所以監(jiān)聽tableView的ContentSize高度即可得出有無數(shù)據(jù)。
優(yōu)點:我們可以創(chuàng)建一個tableView的Base類,在這個類里實現(xiàn)監(jiān)聽,所有有需要展示無數(shù)據(jù)的tableView都可以繼承它,不需要添加一行代碼,就可以實現(xiàn)我們的需求。
結(jié)果: 果斷采用啊?
知識鋪墊: KVO的簡單介紹可以參考我的上一篇文章UIWebView高度自適應(yīng)(基于KVO)-->2.知識鋪墊。
詳細(xì)介紹可以參考這篇文章如何優(yōu)雅地使用KVO
我使用的就是facebook的開源框架KVOController
3.實現(xiàn)(主要代碼)
//.h文件
#import <UIKit/UIKit.h>
@interface BaseTableView : UITableView
//無數(shù)據(jù)時的高度,默認(rèn)20(因為我們有可能會加footerView和headerView,這個時候無數(shù)據(jù)的高度就不為0了)
//row 的高度一般不會小于30,所以選了個折中的高度20;如果無數(shù)據(jù)時的高度大于20,可以在初始化后重新設(shè)置這個高度
@property (nonatomic, assign) CGFloat noDataHeight;
@end
//.m文件
#import "BaseTableView.h"
#import "FBKVOController.h"
@interface BaseTableView()
@property (nonatomic, strong) FBKVOController *kvoController;
@property (nonatomic, strong) UILabel *stringLabel;
@end
@implementation BaseTableView
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style
{
self = [super initWithFrame:frame style:style];
if (self){
//默認(rèn)無數(shù)據(jù)高度
self.noDataHeight = 20;
[self drawView];
[self initFBKVO];
}
return self;
}
//可以自定義的view,可以添加圖片按鈕等,這里只是簡單的顯示個label
- (void)drawView{
_stringLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 20)];
_stringLabel.center = self.center;
_stringLabel.text = @"空空如也~~";
_stringLabel.hidden = YES;
_stringLabel.font = [UIFont systemFontOfSize:15];
_stringLabel.textAlignment = NSTextAlignmentCenter;
_stringLabel.textColor = [UIColor blackColor];
[self addSubview:_stringLabel];
}
//關(guān)鍵代碼
- (void)initFBKVO{
//KVO
__weak typeof (self) weakSelf = self;
self.kvoController = [FBKVOController controllerWithObserver:self];
[self.kvoController observe:self keyPath:@"contentSize" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSString *,id> * _Nonnull change) {
// contentSize有了變化即會走這里
CGFloat height = weakSelf.contentSize.height;
//如果高度大于我們規(guī)定的無數(shù)據(jù)時的高度則隱藏?zé)o數(shù)據(jù)界面,否則展示
if ( height > weakSelf.noDataHeight){
_stringLabel.hidden = YES;
}else {
_stringLabel.hidden = NO;
}
}];
}
@end
4.使用示例
#import "BaseTableView.h"
//...
@property (nonatomic, strong) BaseTableView *tableView;
//...
- (void)drawView{
_tableView = [[BaseTableView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, ScreenHeight) style:UITableViewStylePlain];
//如果有必要設(shè)置的話
// _tableView.noDataHeight = 30;
}
5.總結(jié)
這種實現(xiàn)相對來講還是很方便的,如果無數(shù)據(jù)界面有按鈕,直接寫個代理或者用block即可,可擴(kuò)展性很強(qiáng),簡單方便,希望可以幫到你,如果對你有所幫助,記得點贊哦。