美文网首页iOS Developer
多个请求时如何让加载中图标一直转,直到最后一个请求结束

多个请求时如何让加载中图标一直转,直到最后一个请求结束

作者: 大脸猫l | 来源:发表于2017-02-09 22:46 被阅读0次

序言

在网络请求时,我们一般会显示加载中...图标,如典型的菊花转转转,告知用户数据正在加载,那么如果同时有多个网络请求,必须等到最后一个请求结束才能移除图标,关键是我们不知道哪一个请求最后结束,由于近期公司项目进行大的改动,我负责优化了这一块,所以写了一套关于这方面的框架,希望对大家有所帮助,非喜勿喷哈,毕竟能力有限
下面写了两套,一套是网络请求时显示转转转,一套是文字弹窗提示,都是加到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];
}

信号量的作用是锁住一段代码,防止异步加载时造成数据混乱

相关文章

网友评论

    本文标题:多个请求时如何让加载中图标一直转,直到最后一个请求结束

    本文链接:https://www.haomeiwen.com/subject/xyxwittx.html