iOS 轻松实现页面无数据、无网络、请求出错的友好提示

本文主要是讲讲自己在项目中基于 MJRefresh 封装的一套当页面出现异常情况时给出友好提示页面 YYLrefresh 的实现思路。
Github下载地址: YYLrefresh

实现思路

  1. 采用低侵入式的 category来实现。
    • category不需要通过增加子类而增加现有类的行为(方法), 且类目中的方法与原始类方法基本没有区别。
    • 通过 category 可以将庞大一个类的方法进行划分,从而便于代码的日后的维护、更新以及提高代码的阅读性。
  2. 采用插座式的设计无数据、无网络、请求出错页面方便产品的个性化需求,并且提供默认实现。

具体实现

代码目录.png

下面先来看具体实现的头文件UIScrollView+Refresh.h

  1. 首先定义一个枚举用来区分当前页面的类型
typedef enum : NSUInteger {
    YYLLoadErrorTypeDefalt,
    YYLLoadErrorTypeNoNetwork,      //没有网络
    YYLLoadErrorTypeRequest,        //请求接口 后台报错
    YYLLoadErrorTypeNoData,         //当前页面没有数据
} RELoadErrorType;
  1. 下面定义的属性,主要是用来决定用 UIScrollView、UITableView...及其子类实现的页面是否显示下拉刷新,上啦加载功能及其回调 Block。
/**
 *  是否显示表格的头部刷新
 */
@property(nonatomic, assign) BOOL isShowHeaderRefresh;

/**
 *  是否显示表格的尾部刷新
 */
@property(nonatomic, assign) BOOL isShowFooterRefresh;


/**
 *  表格头部刷新调用的Block
 */
@property(nonatomic, copy) RERefreshTableViewRefreshingBlock headerRefreshingBlock;

/**
 *  表格尾部刷新调用的Block
 */
@property(nonatomic, copy) RERefreshTableViewRefreshingBlock footerRefreshingBlock;
  1. 下面属性主要是用来设置页面显示的类型
/**
 *  设置页面显示的类型
 */
@property(nonatomic, assign) RELoadErrorType loadErrorType;

/**
 *  数据是否全部加载完
 */
@property(nonatomic, assign) BOOL isDataLoaded;

/**
 是否第一次加载
 */
@property(nonatomic, assign) BOOL isFirstLoading;

/**
 *  停止刷新
 */
- (void)endRefreshing;
  1. 下面是默认的无数据、无网络、请求出错页面提示,可以根据产品的需求替换成自己实现的 View。 具体使用见项目中的 Demo 实现。
/**
 *  没有网络时显示的视图
 */
@property(nonatomic, strong) UIView *refreshNoNetworkView;

/**
 *  访问出错时显示的视图
 */
@property(nonatomic, strong) UIView *refreshRequestErrorView;

/**
 *  没有数据显示的视图
 */
@property(nonatomic, strong) UIView *refreshNoDataView;

/**
 *  错误视图的tableview容器
 */
@property(nonatomic, strong) UITableView *refreshErrorTableView;

UIScrollView+Refresh.m 具体实现代码的详解:
.m 文件主要是重写 .h文件中的各个属性的 get 和 set 方法, 然后借助 objc_setAssociatedObject将属性关联上对象。具体实现这里就不一一解释了。主要来看一下下面这个核心的方法实现:

- (void)setLoadErrorType:(YYLLoadErrorType)loadErrorType {
    if (self.refreshNoNetworkView.superview) [self.refreshNoNetworkView removeFromSuperview];
    if (self.refreshRequestErrorView.superview) [self.refreshRequestErrorView removeFromSuperview];
    if (self.refreshNoDataView.superview) [self.refreshNoDataView removeFromSuperview];
    if (loadErrorType == YYLLoadErrorTypeNoNetwork) {
        self.isShowFooterRefresh = NO;
        [self addSubview:self.refreshNoNetworkView];
        [self.refreshNoNetworkView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(0);
            make.width.mas_equalTo(self.mas_width);
            make.top.mas_equalTo(0);
            make.height.mas_equalTo(self.mas_height);
        }];
        
    } else if (loadErrorType == YYLLoadErrorTypeRequest) {
        self.isShowFooterRefresh = NO;
        [self addSubview:self.refreshRequestErrorView];
        [self.refreshRequestErrorView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(0);
            make.width.mas_equalTo(self.mas_width);
            make.top.mas_equalTo(0);
            make.height.mas_equalTo(self.mas_height);
        }];
    } else if (loadErrorType == YYLLoadErrorTypeNoData) {
        self.isShowFooterRefresh = NO;
        [self addSubview:self.refreshNoDataView];
        [self.refreshNoDataView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(0);
            make.width.mas_equalTo(self.mas_width);
            make.top.mas_equalTo(0);
            make.height.mas_equalTo(self.mas_height);
        }];
    }
    objc_setAssociatedObject(self, &loadErrorTypeKey, @(loadErrorType), OBJC_ASSOCIATION_ASSIGN);
    [self endRefreshing];
}

这个方法主要是通过用户设置的类型 loadErrorType 来决定该怎样显示页面: 具体实现是将原来的页面上显示的辅助视图移除掉,根据类型显示新的视图。新视图的位置大小与页面相同。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  • 每到毕业季,总会接到很多学弟学妹关于未来的困惑,在读研和工作中质疑着自己的选择。已经踏入工作岗位的总会怀...
    名夏有余音阅读 303评论 1 1
  • 看完白鹿原,居然久久不能睡着,一个个人物鲜活地出现在我的脑海里。白嘉轩,他固执,封建,但是他的担当,宽容,耿直,还...
    爱微笑的娜子阅读 341评论 2 1
  • 以前我一直认为自己是个善于发现缺点和改正缺点的人。那样过了好多年之后竟有了一个荒唐的观点:觉得自己是个没有什么缺点...
    A有翅膀的猫阅读 1,617评论 3 5
  • 假装像个成熟人一样,冷静的生活,不应放飞自我,最后唱首离歌。
    莞尔听风阅读 121评论 0 2