DZNEmptyDataSet 是一个嵌入 UITableView/UICollectionView 超类的范畴(category),当视图没有要显示的内容时,它用于显示空数据集界面。
这是 iOS 内建的标准,用于处理空表和集合视图。默认情况下,如果你的表视图是空的,屏幕上什么也不会显示,就是一片空白,它给用户的体验不是很好,因为用户不知道空白是APP错误/Bug还是网络异常原因引起的,还是用户应该自己创建内容去填充空白。
使用这个库,你只需要一些协议,iOS 就会很好地处理集合视图,然后合理美观地显示出用户信息。
- DZNEmptyDataSet 效果图:
特点
- 兼容 UITableView 和 UICollectionView 。 也兼容 UISearchDisplayController 和 UIScrollView 。
- 通过显示图像/标题标签/描述标签/按钮,给出布局和外观的多种可能性。
- 使用 NSAttributedString 得到更容易的外观定制。
- 使用 Auto Layout 以自动将内容集中到表格视图,并支持自动旋转。 也接受自定义垂直和水平对齐。
- 背景颜色可定制。
- 允许在整个表格矩形上轻敲手势(有助于放弃第一个响应者或类似操作)。
- 对于更高级的自定义,它允许自定义视图。
- 兼容 Storyboard。
- 兼容iOS 6,tvOS 9或更高版本。
- 兼容iPhone,iPad和Apple TV。
- 支持 App Store 。
这个库已经被设计为不需要通过扩展(extend) UITableView 或 UICollectionView 类的方式来实现了。 使用 UITableViewController 或 UICollectionViewController 类仍然可以奏效。 只要通过遵循DZNEmptyDataSetSource 和 DZNEmptyDataSetDelegate 协议,您将能够完全自定义应用程序的空状态的内容和外观。
安装
支持 CocoaPods 导入
pod 'DZNEmptyDataSet'
使用
#import "EmptyTableViewController.h"
static NSString *identifier = @"Cell";
@interface EmptyTableViewController ()<DZNEmptyDataSetSource, DZNEmptyDataSetDelegate>
@end
@implementation EmptyTableViewController
#define BUTTONTITLE @"重新加载"
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.emptyDataSetSource = self;
self.tableView.emptyDataSetDelegate = self;
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
cell.textLabel.text = @"no empty";
return cell;
}
#pragma mark - DZNEmptyDataSetSource Methods
#pragma mark - 空白页显示标题
- (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView
{
NSString *text = @"No Data";
UIFont *font = [UIFont boldSystemFontOfSize:17];
UIColor *textColor = [UIColor blackColor];
NSMutableDictionary *attributes = [NSMutableDictionary new];
[attributes setObject:font forKey:NSFontAttributeName];
[attributes setObject:textColor forKey:NSForegroundColorAttributeName];
return [[NSAttributedString alloc] initWithString:text attributes:attributes];
}
#pragma mark - 空白页显示详细描述
- (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView
{
NSString *text = @"No Message";
UIFont *font = [UIFont systemFontOfSize:14];
UIColor *textColor = [UIColor grayColor];
NSMutableDictionary *attributes = [NSMutableDictionary new];
NSMutableParagraphStyle *paragraph = [NSMutableParagraphStyle new];
paragraph.lineBreakMode = NSLineBreakByWordWrapping;
paragraph.alignment = NSTextAlignmentCenter;
if (font) [attributes setObject:font forKey:NSFontAttributeName];
if (textColor) [attributes setObject:textColor forKey:NSForegroundColorAttributeName];
if (paragraph) [attributes setObject:paragraph forKey:NSParagraphStyleAttributeName];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
return attributedString;
}
#pragma mark - 空白页显示图片
- (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView
{
return [UIImage imageNamed:@"emptyimg.png"];
}
#pragma mark - 空白页显示按钮
- (NSAttributedString *)buttonTitleForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state
{
NSString *text = BUTTONTITLE;
UIFont *font = [UIFont systemFontOfSize:16.0];
UIColor *textColor = [UIColor whiteColor];
NSMutableDictionary *attributes = [NSMutableDictionary new];
if (font) [attributes setObject:font forKey:NSFontAttributeName];
if (textColor) [attributes setObject:textColor forKey:NSForegroundColorAttributeName];
return [[NSAttributedString alloc] initWithString:text attributes:attributes];
}
#pragma mark - 设置按钮的背景颜色
- (UIImage *)buttonBackgroundImageForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state
{
CGSize titleSize = [Tool calcString:BUTTONTITLE fontSize:[UIFont systemFontOfSize:24] andHeight:24];
UIImage* image = [Tool buttonImageFromColor:[UIColor blackColor] size:titleSize];
UIEdgeInsets capInsets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
UIEdgeInsets rectInsets = UIEdgeInsetsZero;
return [[image resizableImageWithCapInsets:capInsets resizingMode:UIImageResizingModeStretch] imageWithAlignmentRectInsets:rectInsets];
}
#pragma mark - 设置空白页面的背景色
- (UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView
{
return [UIColor whiteColor];
}
#pragma mark - DZNEmptyDataSetDelegate Methods
#pragma mark - 询问是否应该呈现和显示空白页面(默认为YES)
- (BOOL)emptyDataSetShouldDisplay:(UIScrollView *)scrollView
{
return YES;
}
#pragma mark - 请求代理空数据集在显示时是否应该淡入。 (默认值为YES)
- (BOOL)emptyDataSetShouldFadeIn:(UIScrollView *)scrollView
{
return YES;
}
#pragma mark - 强制显示空数据集:当项目数量大于0时,请求代理是否仍应显示空数据集。(默认值为NO)
- (BOOL)emptyDataSetShouldBeForcedToDisplay:(UIScrollView *)scrollView
{
return NO;
}
#pragma mark - 获取允许交互权限(默认为YES):
- (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView
{
return YES;
}
#pragma mark - 获取允许滚动权限(默认值为NO):
- (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView
{
return NO;
}
#pragma mark - 获取允许图像动画权限(默认值为NO):
- (BOOL)emptyDataSetShouldAnimateImageView:(UIScrollView *)scrollView
{
return NO;
}
#pragma mark - 空白数据集 视图被点击 时触发该方法:
- (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view
{
NSLog(@"视图被点击");
}
#pragma mark - 空白数据集 按钮被点击时 触发该方法:
- (void)emptyDataSet:(UIScrollView *)scrollView didTapButton:(UIButton *)button
{
NSLog(@"按钮被点击");
}
#pragma mark - 空白页将要出现
- (void)emptyDataSetWillAppear:(UIScrollView *)scrollView
{
}
#pragma mark - 空白页已经出现
- (void)emptyDataSetDidAppear:(UIScrollView *)scrollView
{
}
#pragma mark - 空白页将要消失
- (void)emptyDataSetWillDisappear:(UIScrollView *)scrollView
{
}
#pragma mark - 空白页已经消失
- (void)emptyDataSetDidDisappear:(UIScrollView *)scrollView
{
}
@end
- 如果需要更复杂的布局,也可以返回自定义视图:
- (UIView *)customViewForEmptyDataSet:(UIScrollView *)scrollView {
UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[activityView startAnimating];
return activityView;
}
效果图:
- 图像视图动画
#pragma mark - DZNEmptyDataSetSource
#pragma mark 空白页显示图片
- (nullable UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView {
return [UIImage imageNamed:@"emptyimg"];
}
#pragma mark 图像视图动画: 旋转
- (CAAnimation *)imageAnimationForEmptyDataSet:(UIScrollView *)scrollView
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath: @"transform"];
animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2, 0.0, 0.0, 1.0)];
animation.duration = 0.25;
animation.cumulative = YES;
animation.repeatCount = MAXFLOAT;
return animation;
}
效果图:
- 图像视图动画:缩放
#pragma mark - DZNEmptyDataSetSource
#pragma mark - 图像视图动画:缩放
- (nullable UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView {
return [UIImage imageNamed:@"emptyimg"];
}
#pragma mark 图像视图动画
- (CAAnimation *)imageAnimationForEmptyDataSet:(UIScrollView *)scrollView
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds"];
animation.duration = 1.25;
animation.cumulative = NO;
animation.repeatCount = MAXFLOAT;
animation.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 45, 45)];
return animation;
}
#pragma mark - DZNEmptyDataSetDelegate
- (BOOL)emptyDataSetShouldAnimateImageView:(UIScrollView *)scrollView {
return YES;
}
效果图:
- 可以将组件彼此上下分离(默认分隔为11个分):
#pragma mark - 将组件彼此上下分离
- (CGFloat)spaceHeightForEmptyDataSet:(UIScrollView *)scrollView {
return 25.0f;
}
效果图:
还有更多更好玩的设置,可以多试试