项目需求
实时监测网络,无网络的时候展示如下的占位图
实现此功能需要借助RealReachability
为UIViewController
添加Category
- UIViewController+JNetWork.h
@interface UIViewController (JNetWork)
/**
黑名单功能
@param list 控制器列表
*/
+ (void)addNetworkBlackList:(NSArray <NSString *>*)list;
+ (UIViewController*)currentViewController;
/**
显示无网络
*/
-(void)showNoNetwork;
/**
隐藏无网络
*/
-(void)hiddenNoNetwork;
/**
刷新
*/
- (void)reloadRequest;
@end
- UIViewController+JNetWork.m
static const void *NetworkArrayKey = &NetworkArrayKey;
static const void *BlackViewControllerKey = &BlackViewControllerKey;
@implementation UIViewController (JNetWork)
+ (void)setNetworkArray:(NSArray <NSString *>*)networkArray {
objc_setAssociatedObject(self, NetworkArrayKey, networkArray, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (NSArray <NSString *>*)networkArray {
return objc_getAssociatedObject(self, NetworkArrayKey);
}
- (void)showNoNetwork {
if (![UIViewController needShowNetworkView]) {
return;
}
NSInteger tag = 0;
for (UIView* view in self.view.subviews) {
if ([view isKindOfClass:[EMNetworkView class]]) {
tag ++;
}
}
if(tag > 0)return;
EMNetworkView *networkView = [[EMNetworkView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(reloadRequest)];
[networkView addGestureRecognizer:tap];
[self.view addSubview:networkView];
}
- (void)hiddenNoNetwork {
for (UIView* view in self.view.subviews) {
if ([view isKindOfClass:[EMNetworkView class]]) {
[view removeFromSuperview];
}
}
}
/**
刷新
*/
- (void)reloadRequest {
}
+ (void)addNetworkBlackList:(NSArray <NSString *>*)list {
[self setNetworkArray:list];
}
+ (BOOL)needShowNetworkView {
NSString *vcStr = NSStringFromClass([self currentViewController].class);
return ![[self networkArray] containsObject:vcStr];
}
//获取Window当前显示的ViewController
+ (UIViewController*)currentViewController{
//获得当前活动窗口的根视图
UIViewController* vc = [UIApplication sharedApplication].keyWindow.rootViewController;
while (1)
{
//根据不同的页面切换方式,逐步取得最上层的viewController
if ([vc isKindOfClass:[UITabBarController class]]) {
vc = ((UITabBarController*)vc).selectedViewController;
}
if ([vc isKindOfClass:[UINavigationController class]]) {
vc = ((UINavigationController*)vc).visibleViewController;
}
if (vc.presentedViewController) {
vc = vc.presentedViewController;
}else{
break;
}
}
return vc;
}
@end
如何使用
在AppDelegate利用RealReachability监听网络
// 网络监听
[GLobalRealReachability startNotifier];
// 网络变化通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(networkChanged:)
name:kRealReachabilityChangedNotification
object:nil];
网络变化的时候展示或者隐藏占位图
- (void)networkChanged:(NSNotification *)notification
{
RealReachability *reachability = (RealReachability *)notification.object;
ReachabilityStatus status = [reachability currentReachabilityStatus];
DLog(@"currentStatus:%@",@(status));
if (status == RealStatusNotReachable) {
[[UIViewController currentViewController] showNoNetwork];
}else{
[[UIViewController currentViewController] hiddenNoNetwork];
}
}
增加了黑名单功能
一些控制器不需要展示占位图,例如登陆,注册等页面
在AppDelegate中添加如下代码
[UIViewController addNetworkBlackList:@[@"LoginViewController",@"RegisteredController"]];
主动监测网络变化
主动监测网络变化可以放在网络请求中,每次请求接口的时候监测网络,这么就能比较完美的,在恰当的实际展示无网络占位图
[GLobalRealReachability reachabilityWithBlock:^(ReachabilityStatus status) {
if (status == RealStatusNotReachable) {
[[UIViewController currentViewController] showNoNetwork];
}else{
[[UIViewController currentViewController] hiddenNoNetwork];
}
}];
如果在网络请求中添加了如上方法,那么就要在控制器里重写 reloadRequest
当用户点击的时候重新请求接口,触发网络监测,此时有网络的话,就会移除占位图
代码上传到了github