序言
在网络请求时,我们一般会显示加载中...图标,如典型的菊花转转转,告知用户数据正在加载,那么如果同时有多个网络请求,必须等到最后一个请求结束才能移除图标,关键是我们不知道哪一个请求最后结束,由于近期公司项目进行大的改动,我负责优化了这一块,所以写了一套关于这方面的框架,希望对大家有所帮助,非喜勿喷哈,毕竟能力有限
下面写了两套,一套是网络请求时显示转转转,一套是文字弹窗提示,都是加到keyWindow上
上代码
///.h文件
//这里主要用MB的框架,好用
#import "MBProgressHUD.h"
@interface JSProgressHUD : NSObject
///统一Indicator(显示) 主线程调用
+ (void)showIndicator;
///统一Indicator(隐藏) 主线程调用
+ (void)hideIndicator;
///统一弹窗显示格式 主线程调用
+ (void)showInfo:(NSString *)info;
@end
上面提示在主线程调用,主要是因为我创建的MBProgressHUD实例是单例,在其它线程调用时与dispatch_once发生了死锁,具体原因没查出来
如果不写成单例,前一个网络请求结束,在开启下个请求时,菊花会闪一下,体验不好
///.m文件
#import "JSProgressHUD.h"
//在获取keyWindow时,用了delegate,主要是因为与系统的alertView发生了冲突,其实在平常获取keyWindow时,这种写法才是正规的
#define Key_Window [UIApplication sharedApplication].delegate.window
@implementation JSProgressHUD
///菊花
static long loadCount = 0;//声明静态变量
static MBProgressHUD *shareHud;
///alertText
static long loadTextCount = 0;
static MBProgressHUD *textHud;
///创建信号量和菊花
+ (dispatch_semaphore_t)shareLockSignal{
static dispatch_semaphore_t lockSignal;
static dispatch_once_t once;
dispatch_once(&once, ^{
lockSignal = dispatch_semaphore_create(1);
shareHud = [MBProgressHUD showHUDAddedTo:Key_Window animated:YES];
});
return lockSignal;
}
///创建信号量和弹窗
+ (dispatch_semaphore_t)shareTextLockSignal{
static dispatch_semaphore_t lockSignal;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
lockSignal = dispatch_semaphore_create(1);
textHud = [MBProgressHUD showHUDAddedTo:Key_Window animated:YES];
textHud.userInteractionEnabled = NO;
textHud.bezelView.backgroundColor = [UIColor darkGrayColor];
textHud.contentColor = [UIColor whiteColor];
textHud.mode = MBProgressHUDModeText;
textHud.label.numberOfLines = 0;
textHud.center = CGPointMake(ScreenWidth/2, ScreenHeight/2);
});
return lockSignal;
}
///显示菊花
+ (void)showIndicator{
dispatch_semaphore_t lockSignal = [self shareLockSignal];
dispatch_semaphore_wait(lockSignal, DISPATCH_TIME_FOREVER);
loadCount++;
shareHud.frame = Key_Window.bounds;
[Key_Window addSubview:shareHud];
dispatch_semaphore_signal(lockSignal);
}
///隐藏菊花
+ (void)hideIndicator{
dispatch_semaphore_t lockSignal = [self shareLockSignal];
dispatch_semaphore_wait(lockSignal, DISPATCH_TIME_FOREVER);
loadCount--;
dispatch_async(dispatch_get_main_queue(), ^{
//网络请求数量为0时,移除菊花
if (loadCount == 0) {
[shareHud removeFromSuperview];
}
});
dispatch_semaphore_signal(lockSignal);
}
///显示弹窗内容
+ (void)showInfo:(NSString *)info{
dispatch_semaphore_t lockSignal = [self shareTextLockSignal];
dispatch_semaphore_wait(lockSignal, DISPATCH_TIME_FOREVER);
loadTextCount++;
if (loadTextCount == 1) {//加入判断,不管有多少个文字提示,只显示第一条
textHud.label.text = NSLocalizedString(info, @"HUD message title");
textHud.center = CGPointMake(ScreenWidth/2, ScreenHeight/2);
[Key_Window addSubview:textHud];
//移除
dispatch_async(dispatch_get_main_queue(), ^{
loadTextCount = 0;
NSTimer *timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(removeTextHud:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
});
}
dispatch_semaphore_signal(lockSignal);
}
//移除textHud timer
+ (void)removeTextHud:(NSTimer *)timer{
[textHud removeFromSuperview];
[timer invalidate];
}
信号量的作用是锁住一段代码,防止异步加载时造成数据混乱
网友评论