记一种页面loading动画实现套路
一、需求
1. 首次进入这个页面需要有一个loading动画,当首次加载出错时,需要展示一个错误页,点击错误页可以重新加载,重新加载也需要loading动画。
2. 去到下级页面再返回此页面时,需要重新请求数据刷新页面,这次请求数据时不需要loading动画,且请求数据出错时,也不需要展示错误页,页面保持原样。
以上需求,我们如何实现这样的loading动画逻辑呢?
二、实现
直接上代码:
- (void)viewDidLoad
{
[super viewDidLoad];
[self setUpUI];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//isMovingToParentViewController是iOS 5 之后系统提供的API
BOOL needLoadingAnimation = self.isMovingToParentViewController;
[self requestDataAnimated:needLoadingAnimation];
}
- (void)requestDataAnimated:(BOOL)animated
{
//1.根据animated添加loading动画
if (animated) {
[IGPageLoadingView showInPageView:self.view];
}
[IGNetworkManager requestWithReq:nil successCallback:^(NSInteger resultCode, NSString *resultMsg, id body) {
//2.请求成功后移除loading动画
[IGPageLoadingView removeFromPageView:self.view];
[self refresh];
} failedCallback:^(NSInteger resultCode, NSString *resultMsg, id body) {
//3.请求失败也要移除loading动画
[IGPageLoadingView removeFromPageView:self.view];
//4.根据animated添加错误页
if (animated) {
[IGPageErrorView showInPageView:self.view tapAction:^{
[self requestDataAnimated:YES];
}];
}
}];
}
代码解析:
1. 在viewWillAppear中发起请求,这样每一次进入页面都会刷新,再根据isMovingToParentViewController来判断是否为首次进入,首次进入则添加loading动画。
2. 请求数据方法添加animated参数,根据animated来判断是否添加loading动画。
3. 如果是一个简单页面,不需要每次进入都刷新,也不要支持下拉刷新,则loading动画添加方法如下:
- (void)viewDidLoad
{
[super viewDidLoad];
[self setUpUI];
[self requestData];
}
- (void)requestData
{
//1.添加loading动画
[IGPageLoadingView showInPageView:self.view];
[IGNetworkManager requestWithReq:nil successCallback:^(NSInteger resultCode, NSString *resultMsg, id body) {
//2.请求成功后移除loading动画
[IGPageLoadingView removeFromPageView:self.view];
[self refresh];
} failedCallback:^(NSInteger resultCode, NSString *resultMsg, id body) {
//3.请求失败添加错误页(添加错误页会自动移除loading动画)
[IGPageErrorView showInPageView:self.view tapAction:^{
[self requestData];
}];
}];
}
三、知识扩展
iOS 5 之后,UIViewController新增以下4个方法:
/*
These four methods can be used in a view controller's appearance callbacks to determine if it is being
presented, dismissed, or added or removed as a child view controller. For example, a view controller can
check if it is disappearing because it was dismissed or popped by asking itself in its viewWillDisappear:
method by checking the expression ([self isBeingDismissed] || [self isMovingFromParentViewController]).
*/
#if UIKIT_DEFINE_AS_PROPERTIES
@property(nonatomic, readonly, getter=isBeingPresented) BOOL beingPresented NS_AVAILABLE_IOS(5_0);
@property(nonatomic, readonly, getter=isBeingDismissed) BOOL beingDismissed NS_AVAILABLE_IOS(5_0);
@property(nonatomic, readonly, getter=isMovingToParentViewController) BOOL movingToParentViewController NS_AVAILABLE_IOS(5_0);
@property(nonatomic, readonly, getter=isMovingFromParentViewController) BOOL movingFromParentViewController NS_AVAILABLE_IOS(5_0);
#else
- (BOOL)isBeingPresented NS_AVAILABLE_IOS(5_0);
- (BOOL)isBeingDismissed NS_AVAILABLE_IOS(5_0);
- (BOOL)isMovingToParentViewController NS_AVAILABLE_IOS(5_0);
- (BOOL)isMovingFromParentViewController NS_AVAILABLE_IOS(5_0);
#endif
看接口注释能知道,如果通过presentViewController方法弹出的Modal ViewController,则首次viewWillAppear时isBeingPresented为YES,如果是UITabBarController、UINavigationController等的子视图,则首次viewWillAppear时isMovingToParentViewController为YES,反之为NO。我们通过demo来验证,在此我直接贴上结果:
2019-01-15 15:52:52.996965+0800 test[87924:3898152]
RootViewController, isBeingPresented = NO isMovingToParentViewController = NO
2019-01-15 15:52:53.011739+0800 test[87924:3898152]
ModalVC: isBeingPresented = YES isMovingToParentViewController = NO
2019-01-15 15:52:53.017630+0800 test[87924:3898152]
TestVC: isBeingPresented = NO isMovingToParentViewController = YES
// 去到下级页面再返回
2019-01-15 15:52:55.875078+0800 test[87924:3898152]
TestVC: isBeingPresented = NO isMovingToParentViewController = NO
在对应VC的viewWillAppear方法进行打印,TestVC是导航栈上的vc,可以看到结果和官方注释一致。同时发现window的rootViewController的isBeingPresented和isMovingToParentViewController 都是 NO。isBeingDismissed和isMovingFromParentViewController同理。
最后感谢大家的阅读,欢迎指出问题和提出建议。
上一篇: 用CSS3制作Loading加载动画
下一篇: android > 获取当前位置