IOS空数据页面,网络加载失败以及重新登陆View的封装(不需要继承)
一.问题
对于B2C和B2B项目的开发者,可能会有一个订单列表为空,或者其他收藏页面为空,用户token失效,判断用户要重新登陆,以及后台服务错误等提示。本篇课文,看完大约10分钟。
原本自己不想写空页面的展示,网络加载失败或者重新登陆的封装,想从网上找一个第三方的view,但找了很多都是让我继承他人的控制器,而我自己写好了继承基本的控制器,如果继承他人的控制器,自己的代码需要改比较多的地方,所以决定自己写(如果其他开发者,也有同样的困扰,可以直接复用,不需要继承)
二.不谈虚的,直接上源代码
1.首先写一个协议,以后view布局遵守此协议,实现其方法实现布局。
#import <Foundation/Foundation.h> @protocol IOAProtocol <NSObject>
@optional
// 需要 [super addSubViews]
- (void)addSubViews;
// 不需要[super prepare] 用作布局
- (void)prepare; @end
2.订单空页面的UI
#import <UIKit/UIKit.h>
#import "IOAProtocol.h" @interface IOAEmptyPageView : UIView <IOAProtocol>//遵守协议
@property (nonatomic, readonly, strong) UIImageView *imageView;
@property (nonatomic, readonly, strong) UILabel *titleLabel;
@property (nonatomic, readonly, strong) UILabel *subTitleLabel;
//可能有的空页面需要点击一下跳转(备用)
@property (nonatomic, readonly, strong) UIButton *refreshButton; @property (nonatomic, copy) void (^clickCallback)(id object);
@end
.m文件
#import "IOAEmptyPageView.h" @interface IOAEmptyPageView ()
@property (nonatomic, readwrite, strong) UIImageView *imageView;
@property (nonatomic, readwrite, strong) UILabel *titleLabel;
@property (nonatomic, readwrite, strong) UILabel *subTitleLabel;
@property (nonatomic, readwrite, strong) UIButton *refreshButton; @end @implementation IOAEmptyPageView
- (void)dealloc { } - (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor whiteColor];
[self addSubViews];
[self prepare];
} return self;
} - (void)addSubViews {
[self addSubview:self.imageView];
[self addSubview:self.titleLabel];
[self addSubview:self.subTitleLabel];
[self addSubview:self.refreshButton];
} //利用masonry进行适配
- (void)prepare { [self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self);
make.bottom.equalTo(self.mas_centerY).offset(-);
make.left.greaterThanOrEqualTo(self);
make.right.lessThanOrEqualTo(self);
}]; [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.imageView);
make.top.equalTo(self.imageView.mas_bottom).offset();
make.left.greaterThanOrEqualTo(self);
make.right.lessThanOrEqualTo(self);
make.height.equalTo(@);
}]; [self.subTitleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.titleLabel);
make.top.equalTo(self.titleLabel.mas_bottom).offset();
make.left.greaterThanOrEqualTo(self);
make.right.lessThanOrEqualTo(self);
make.height.equalTo(@);
}]; [self.refreshButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.subTitleLabel);
make.top.equalTo(self.subTitleLabel.mas_bottom).offset();
// make.left.greaterThanOrEqualTo(self);
// make.right.lessThanOrEqualTo(self);
make.height.equalTo(@);
make.width.equalTo(@);
}];
} #pragma mark - Actions
- (void)clickedRefreshButton:(id)button {
if (self.clickCallback) {
self.clickCallback(self);
}
} #pragma mark - Setter / Getter
- (UIImageView *)imageView {
if (!_imageView) {
_imageView = [UIImageView new];
_imageView.contentMode = UIViewContentModeCenter;
_imageView.image = [UIImage imageNamed:@"EmptyImage"];
} return _imageView;
} - (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [UILabel new];
_titleLabel.textColor = RGB_HEXString(@"#323232");
_titleLabel.font = [UIFont systemFontOfSize:];
_titleLabel.textAlignment = NSTextAlignmentCenter;
} return _titleLabel;
} - (UILabel *)subTitleLabel {
if (!_subTitleLabel) {
_subTitleLabel = [UILabel new];
_subTitleLabel.textColor = RGB_HEXString(@"#323232");
_subTitleLabel.font = [UIFont systemFontOfSize:];
_subTitleLabel.textAlignment = NSTextAlignmentCenter;
} return _subTitleLabel;
} - (UIButton *)refreshButton {
if (!_refreshButton) {
_refreshButton = [UIButton buttonWithType:UIButtonTypeSystem];
[_refreshButton setTitle:@"重新加载" forState:UIControlStateNormal];
[_refreshButton setTitleColor:RGB_HEXString(@"#323232") forState:UIControlStateNormal];
_refreshButton.titleLabel.font = [UIFont systemFontOfSize:];
[_refreshButton addTarget:self action:@selector(clickedRefreshButton:) forControlEvents:UIControlEventTouchUpInside];
_refreshButton.layer.cornerRadius = ;
_refreshButton.layer.borderColor = RGB_HEXString(@"#323232").CGColor;
_refreshButton.layer.borderWidth = 1.0f;
} return _refreshButton;
}
@end
封装调用方法(无数据提示,无数据跳转,后台服务错误以及token失效,请重新登陆)
#import <UIKit/UIKit.h>
#import "IOAEmptyPageView.h" @interface UIViewController (Progress)
- (void)startProgress;
- (void)stopProgress; - (void)startProgress:(BOOL)animate;
- (void)stopProgress:(BOOL)animate; // 提示框
- (void)showAlertWithTitle:(NSString *)title detail:(NSString *)deatil clickBlock:(void (^)(NSInteger index))clickBlock;
- (void)showCommonAlertWithTitle:(NSString *)title clickBlock:(void(^)(NSInteger index))clickBlock;
//- (void)hideCommonAlert; // 无网络
- (UIView *)showNoNetworkPage;
- (void)dismissNoNetworkPage;
//- (void)clickedNoNetworkPage:(id)object; // 空页面
- (UIView *)showNoDatasPage;
- (void)dismissNoDatasPage;
//订单空页面的提示(目前我用的)
- (UIView *)showNoOrderPage:(NSString *)str withImage:(NSString *)image;
//- (void)clickedNoDatasPage:(id)object; // 服务后台错误
- (UIView *)showServerErrorPage;
- (void)dismissServerErrorPage; - (UIView *)showEmptyPageWith:(UIImage *)image title:(NSString *)title subTitle:(NSString *)subTitle;
- (void)dismissEmptyPage;
- (void)clickedEmptyPage:(id)object; // token 失效 push
// 先弹出当前VC
- (void)showLoginViewController;
// 不弹出当前VC
- (void)showLoginViewControllerNoPop;
/*
* 跳转到登录界面
* @paramater isNeedPopCurVC: YES 要弹出当前VC NO 不需要弹出
*/
- (void)showLoginViewcontrollerWithPopCurrentVC:(BOOL)isNeedPopCurVC;
@end
.m文件实现
#import "UIViewController+Progress.h"
//借助第三方
#import <MBProgressHUD/MBProgressHUD.h>
#import <MMPopupView/MMAlertView.h>
//用户登陆控制器(导入你们自己的loginVc)
#import "IOAUserLoginViewController.h" @implementation UIViewController (Progress)
- (void)startProgress {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
}
- (void)stopProgress {
[MBProgressHUD hideHUDForView:self.view animated:YES];
} - (void)startProgress:(BOOL)animate {
[MBProgressHUD showHUDAddedTo:self.view animated:animate];
}
- (void)stopProgress:(BOOL)animate {
[MBProgressHUD hideHUDForView:self.view animated:NO];
} - (void)showAlertWithTitle:(NSString *)title detail:(NSString *)deatil clickBlock:(void (^)(NSInteger index))clickBlock {
NSArray *items =
@[
MMItemMake(@"取消", MMItemTypeNormal, clickBlock),
MMItemMake(@"确定", MMItemTypeHighlight, clickBlock)]; MMAlertView *alertView = [[MMAlertView alloc] initWithTitle:title detail:deatil items:items];
// alertView.attachedView = self.view;
alertView.attachedView.mm_dimBackgroundBlurEnabled = NO;
alertView.attachedView.mm_dimBackgroundBlurEffectStyle = UIBlurEffectStyleLight; [alertView show];
} - (void)showCommonAlertWithTitle:(NSString *)title clickBlock:(void(^)(NSInteger index))clickBlock {
[self showAlertWithTitle:title detail:nil clickBlock:clickBlock];
} // 无网络
- (UIView *)showNoNetworkPage {
return [self showEmptyPageWith:nil title:@"网络请求失败" subTitle:@"请检查网络"];
}
- (void)dismissNoNetworkPage {
[self dismissEmptyPage];
} // 空页面
- (UIView *)showNoDatasPage { return [self showEmptyPageWith:nil title:@"网络请求成功" subTitle:@"数据为空"];
} //无订单---主要用的
- (UIView *)showNoOrderPage:(NSString *)str withImage:(NSString *)image{
return [self showEmptyOrderWith:[UIImage imageNamed:image] title:nil subTitle:str];
} - (void)dismissNoDatasPage {
[self dismissEmptyPage];
} - (UIView *)showServerErrorPage {
return [self showEmptyPageWith:nil title:@"网络请求失败" subTitle:@"后台服务错误"];
}
- (void)dismissServerErrorPage {
[self dismissEmptyPage];
} - (UIView *)showEmptyPageWith:(UIImage *)image title:(NSString *)title subTitle:(NSString *)subTitle {
for (UIView *view in self.view.subviews) {
if ([view isKindOfClass:[IOAEmptyPageView class]]) {
return view;
}
}
IOAEmptyPageView *emptyView = [IOAEmptyPageView new];
// emptyView.backgroundColor = [UIColor redColor];
if (image) {
emptyView.imageView.image = image;
}
emptyView.titleLabel.text = title;
emptyView.subTitleLabel.text = subTitle;
WS(weakSelf);
emptyView.clickCallback = ^(id object) {
[weakSelf clickedEmptyPage:weakSelf];
[weakSelf dismissEmptyPage];
};
[self.view addSubview:emptyView];
UINavigationBar *navBar = self.navigationController.navigationBar;
UITabBar *tarBar = self.tabBarController.tabBar; CGFloat topOffset = ;
CGFloat bottomOffset = ;
if (!navBar.hidden) {
topOffset = TopHeightOffset;
}
if (!tarBar.hidden) {
bottomOffset = BottomHeightOffset;
} [emptyView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view);
make.top.equalTo(self.view).offset(topOffset);
make.bottom.equalTo(self.view).offset(-bottomOffset);
}];
return emptyView;
} - (UIView *)showEmptyOrderWith:(UIImage *)image title:(NSString *)title subTitle:(NSString *)subTitle {
for (UIView *view in self.view.subviews) {
if ([view isKindOfClass:[IOAEmptyPageView class]]) {
return view;
}
}
IOAEmptyPageView *emptyView = [IOAEmptyPageView new];
if (image) {
emptyView.imageView.image = image;
}
emptyView.titleLabel.text = title;
emptyView.subTitleLabel.text = subTitle;
emptyView.refreshButton.hidden = YES;
WS(weakSelf);
emptyView.clickCallback = ^(id object) {
[weakSelf clickedEmptyPage:weakSelf];
[weakSelf dismissEmptyPage];
};
[self.view addSubview:emptyView];
UINavigationBar *navBar = self.navigationController.navigationBar;
UITabBar *tarBar = self.tabBarController.tabBar; CGFloat topOffset = ;
CGFloat bottomOffset = ;
if (!navBar.hidden&&![subTitle isEqualToString:@"你还没有收藏的商品"]) {
topOffset = TopHeightOffset;
}
if (!tarBar.hidden) {
bottomOffset = BottomHeightOffset;
} [emptyView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view);
make.top.equalTo(self.view).offset(topOffset);
make.bottom.equalTo(self.view).offset(-bottomOffset);
}];
return emptyView;
} - (void)dismissEmptyPage {
for (UIView *view in self.view.subviews) {
if ([view isKindOfClass:[IOAEmptyPageView class]]) {
[view removeFromSuperview];
return;
}
}
}
- (void)clickedEmptyPage:(id)object {
[self dismissEmptyPage];
} // token 失效 push
- (void)showLoginViewController {
[self showLoginViewcontrollerWithPopCurrentVC:YES];
} // 不弹出当前VC
- (void)showLoginViewControllerNoPop {
[self showLoginViewcontrollerWithPopCurrentVC:NO];
} - (void)showLoginViewcontrollerWithPopCurrentVC:(BOOL)isNeedPopCurVC {
if (!self.navigationController) return; IOAUserLoginViewController *loginVC = [IOAUserLoginViewController new];
NSMutableArray *array = [NSMutableArray array];
NSArray *vcList = self.navigationController.viewControllers;
if ([[vcList lastObject] isKindOfClass:[IOAUserLoginViewController class]]) {
return;
}
[array addObjectsFromArray:vcList];
if (array.count > && isNeedPopCurVC) {
[array removeLastObject];
}
[array addObject:loginVC];
[self.navigationController setViewControllers:array animated:YES];
} #if 0
UIAlertController *alert = [UIAlertController alertControllerWithTitle:number message:@"拨打电话" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { }];
UIAlertAction *no = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { }]; unsigned int count = ;
Ivar *ivars = class_copyIvarList([UIAlertController class], &count);
for(int i = ; i<count; i ++) {
Ivar ivar = ivars[i];
NSString *ivarName = [NSString stringWithCString:ivar_getName(ivar) encoding:NSUTF8StringEncoding]; //标题颜色
if ([ivarName isEqualToString:@"_attributedTitle"]) {
NSMutableAttributedString *attr = [[NSMutableAttributedString alloc]initWithString:alert.title attributes:@{NSForegroundColorAttributeName:RGB_HEXString(@"#323232"),NSFontAttributeName:Font()}];
[alert setValue:attr forKey:@"attributedTitle"];
continue;
} //描述颜色
if ([ivarName isEqualToString:@"_attributedMessage"]) {
NSMutableAttributedString *attr = [[NSMutableAttributedString alloc]initWithString:alert.message attributes:@{NSForegroundColorAttributeName:RGB_HEXString(@"#646464"),NSFontAttributeName:Font()}];
[alert setValue:attr forKey:@"attributedMessage"];
continue;
}
}
free(ivars); ivars = class_copyIvarList([UIAlertAction class], &count);
for (int i=; i<count; i++) {
Ivar ivar = ivars[i];
NSString *name = [NSString stringWithCString:ivar_getName(ivar) encoding:NSUTF8StringEncoding];
if ([name isEqualToString:@"_titleTextColor"]) {
[no setValue:RGB_HEXString(@"#323232") forKey:@"titleTextColor"];
[ok setValue:RGB_HEXString(@"#c30d23") forKey:@"titleTextColor"];
}
}
free(ivars); [alert addAction:no];
[alert addAction:ok];
[self presentViewController:alert animated:YES completion:nil];
#endif
@end
3.应用:
[self.viewModel requestOrderShopList:self.requestModel callback:^(IOAResponse *response) {
dispatch_async(dispatch_get_main_queue(), ^{
[self stopProgress];
NSArray <IOAOrderGroup *> *group = response.responseObject;
if (group) {
if (group.count == && self.requestModel.page_no.integerValue == ) {
self.requestModel.page_no = [NSString stringWithFormat:@"%ld", self.requestModel.page_no.integerValue+];
}
[self.dataArr removeAllObjects];
[self.dataArr addObjectsFromArray:response.responseObject];
[self.tableView reloadData];
if (self.dataArr.count == ) {
//空页面
[self showNoOrderPage:@"目前还没有待付款订单" withImage:@"order"];
return ; }
} else {
if ([response isNoNetwork] && self.dataArr.count == ) {
//无网络
[self showNoNetworkPage];
return;
}
if ([response isRequestServerError]) {
//后台错误
[self showServerErrorPage];
return;
}
}
});
}];
可以直接copy,有一个点要主要
[self showServerErrorPage]这些方法,我是继承了三四层,你可以改成类方法,直接用类调用,这些都是源代码,可以用,这个暂不考虑上传git,谢谢观看
IOS空数据页面,网络加载失败以及重新登陆View的封装(不需要继承)的更多相关文章
- 当h5页面图片加载失败后,给定一个默认图
本文主要讨论页面中图片加载失败后替换默认图片的几种方式 重点来了:一定要记住error事件不冒泡. 相关的知识点:jquery的ready方法.$("img").error().i ...
- WebView加载失败或网络异常时,替换WebView的错误界面;
WebView在加载失败时会显示一个失败原因的界面,各个手机显示的界面还都不一样,部分手机还会把Url显示出来:我们要做的就是统一加载失败的界面: 大概思路:在WebView这个控件上面再覆盖一个Vi ...
- SwiftUI - 一步一步教你使用UIViewRepresentable封装网络加载视图(UIActivityIndicatorView)
概述 网络加载视图,在一个联网的APP上可以讲得上是必须要的组件,在SwiftUI中它并没有提供如 UIKit 中的UIActivityIndicatorView直接提供给我们调用,但是我们可以通过 ...
- [IOS]UIWebView 请求网络页面或者加载本地资源页面
UIWebView是一个能够显示网页的IOS视图控件,我们可以用它来访问一个网站.下面是具体的实例: 操作步骤: 1.首先在xib文件中拖放一个UIWebView控件到view中 2.将下载的页面以及 ...
- HBuilder mui 手机app开发 Android手机app开发 ios手机app开发 打开新页面 预加载页面 关闭页面
创建子页面 在mobile app开发过程中,经常遇到卡头卡尾的页面,此时若使用局部滚动,在android手机上会出现滚动不流畅的问题: mui的解决思路是:将需要滚动的区域通过单独的webview实 ...
- iOS网络加载图片缓存策略之ASIDownloadCache缓存优化
iOS网络加载图片缓存策略之ASIDownloadCache缓存优化 在我们实际工程中,很多情况需要从网络上加载图片,然后将图片在imageview中显示出来,但每次都要从网络上请求,会严重影响用 ...
- js/jquery控制页面动态加载数据 滑动滚动条自动加载事件--转他人的
js/jquery控制页面动态加载数据 滑动滚动条自动加载事件--转他人的 相信很多人都见过瀑布流图片布局,那些图片是动态加载出来的,效果很好,对服务器的压力相对来说也小了很多 有手机的相信都见过这样 ...
- HTTP 筛选器 DLL C:\Windows\Microsoft.Net\Framework\v4.0.30319\aspnet_filter.dll 加载失败。数据是错误。
今天在一台win2003的云主机上,安装.net 4.0时,所有的网站都打不开了.打开事件查看器,发现以下错误: HTTP 筛选器 DLL C:\Windows\Microsoft.Net\Frame ...
- 微信页面script标签添加crossorigin=“anonymous”导致页面加载失败
公司一个微信企业号项目,突然出现页面数据加载失败,页面报错信息如下 意思是前端向服务端发送跨域资源请求访问这个js文件,但是服务端并不同意,所以服务端拒绝访问这个地址. 后来发现将crossorigi ...
随机推荐
- [struts2学习笔记] 第二节 使用Maven搞定管理和构造Struts 2 Web应用程序的七个步骤
本文地址:http://blog.csdn.net/sushengmiyan/article/details/40303897 官方文档:http://struts.apache.org/releas ...
- ExtJS学习(二)Ext组件模型
Ext中所有的组件都继承自Ext.component,这种单根继承的模型保证所有组件都拥有相同的通用方法与生命周期,这样在后续对这些组件进行维护管理时将更加便捷,同时也保证了在进行布局时的便利. 组件 ...
- Android的SeekBar和RateBar的使用-android学习之旅(三十二)
SeekBar简介 SeekBar允许用户拖动,进行调节经常用于音量调节等方面. android:thumb设置drawable对象来表示拖动的物体. setOnSeekBarChangeListen ...
- Redefine:Change in the Changing World
EMC World 2014的主题就是REDEFINE.的确,现在科技的发展在重新定义了技术,影响了生活,改变了你我. 对于一个有数万员工,甚至数十万员工的企业来说,Redefine无疑更加具有挑战, ...
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(七)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 打开SpriteBuilder,在文件视图中新建一个文件夹Fon ...
- HBase作为存储方案
HBase存储特点 * Client 1. 包含访问HBase的接口,并维护cache来加快对HBase的访问,比如region的位置信息. * Zookeeper: 1. 选举集群中的Master, ...
- 多态原理探究-从C++编译器角度理解多态的实现原理
理论知识: 当类中声明虚函数时,编译器会在类中生成一个虚函数表. 虚函数表是一个存储类成员函数指针的数据结构. 虚函数表是由编译器自动生成与维护的. virtual成员函数会被编译器放入虚函数表中. ...
- LINUX0.11 内核阅读笔记
一.源码目录 图1 二.系统总体流程: 系统从boot开始动作,把内核从启动盘装到正确的位置,进行一些基本的初始化,如检测内存,保护模式相关,建立页目录和内存页表,GDT表,IDT表.然后进入main ...
- Mybatis逻辑分页原理解析RowBounds
Mybatis提供了一个简单的逻辑分页使用类RowBounds(物理分页当然就是我们在sql语句中指定limit和offset值),在DefaultSqlSession提供的某些查询接口中我们可以看到 ...
- Java中Set的contains()方法
Java中Set的contains()方法 -- hashCode与equals方法的约定及重写原则 翻译人员: 铁锚 翻译时间: 2013年11月5日 原文链接: Java hashCode() a ...