美文网首页iOS源码解读Object-C
SVProgressHUD 源码略读

SVProgressHUD 源码略读

作者: __zimu | 来源:发表于2015-11-18 12:35 被阅读654次

1. MaskType 用于设置与用户交互相关

typedef NS_ENUM(NSUInteger, SVProgressHUDMaskType) {
    SVProgressHUDMaskTypeNone = 1,  // allow user interactions while HUD is displayed
    SVProgressHUDMaskTypeClear,     // don't allow user interactions
    SVProgressHUDMaskTypeBlack,     // don't allow user interactions and dim the UI in the back of the HUD
    SVProgressHUDMaskTypeGradient   // don't allow user interactions and dim the UI with a a-la-alert-view background gradient
};

2. 弹窗的显示时间:

- (NSTimeInterval)displayDurationForString:(NSString*)string {
    return MIN((float)string.length*0.06 + 0.5, 5.0);
    //文字长度 * 0.06 + 0.5 与 5秒 取最小值 最长显示5秒, 最短显示0.5秒
}

3. 显示分为两种:

1>显示完不自动消失,需要手动去 dismiss的

#pragma mark - Show Methods

+ (void)show;
+ (void)showWithMaskType:(SVProgressHUDMaskType)maskType;
+ (void)showWithStatus:(NSString*)status;
+ (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;

+ (void)showProgress:(float)progress;
+ (void)showProgress:(float)progress maskType:(SVProgressHUDMaskType)maskType;
+ (void)showProgress:(float)progress status:(NSString*)status;
+ (void)showProgress:(float)progress status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;

+ (void)setStatus:(NSString*)string; // change the HUD loading status while it's showing
#Pragma mark - 底层方法
#Pragma mark - (.m里  590行)
- (void)showProgress:(float)progress status:(NSString*)string maskType:(SVProgressHUDMaskType)hudMaskType {
      //...
      //...
      ///self.overlayView 是一个 UIControl 目的是 根据不同的 maskType 来设置 用户交互的可行性
    if(!self.overlayView.superview) {
      //如果没有定义 APP拓展 ->  File->New->Target...-> iOS -> App Extension...
#if !defined(SV_APP_EXTENSIONS)  
        NSEnumerator *frontToBackWindows = [UIApplication.sharedApplication.windows reverseObjectEnumerator];
        for (UIWindow *window in frontToBackWindows){
            BOOL windowOnMainScreen = window.screen == UIScreen.mainScreen;
            BOOL windowIsVisible = !window.hidden && window.alpha > 0;
            BOOL windowLevelNormal = window.windowLevel == UIWindowLevelNormal;
            ///弹窗 是添加到了 window 上
            if (windowOnMainScreen && windowIsVisible && windowLevelNormal) {
                [window addSubview:self.overlayView];
                break;
            }
        }
#else
        if(SVProgressHUDExtensionView){
            [SVProgressHUDExtensionView addSubview:self.overlayView];
        }
#endif
    } else {
        // Ensure that overlay will be exactly on top of rootViewController (which may be changed during runtime).
        // 不满足上面3个条件的话  弹窗是添加在 根控制器的最上层
        [self.overlayView.superview bringSubviewToFront:self.overlayView];
    }
    
    if(!self.superview)
        [self.overlayView addSubview:self];
}
      //...
      //...

2>显示完自动消失,不需要手动去 dismiss 的

所谓的自动消失, 就是在底层方法里通过消息循环加一个 timer 来调用 dismiss方法

// stops the activity indicator, shows a glyph + status, and dismisses HUD a little bit later
+ (void)showInfoWithStatus:(NSString *)string;
+ (void)showInfoWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType;

+ (void)showSuccessWithStatus:(NSString*)string;
+ (void)showSuccessWithStatus:(NSString*)string maskType:(SVProgressHUDMaskType)maskType;

+ (void)showErrorWithStatus:(NSString *)string;
+ (void)showErrorWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType;

// use 28x28 white pngs
+ (void)showImage:(UIImage*)image status:(NSString*)status;
+ (void)showImage:(UIImage*)image status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;
#底层方法
      #时间控制
+ (void)showImage:(UIImage *)image status:(NSString *)string maskType:(SVProgressHUDMaskType)maskType {
    NSTimeInterval displayInterval = [[self sharedView] displayDurationForString:string];
    [[self sharedView] showImage:image status:string duration:displayInterval maskType:maskType];
}
      #显示控制
- (void)showImage:(UIImage *)image status:(NSString *)string duration:(NSTimeInterval)duration maskType:(SVProgressHUDMaskType)hudMaskType {
    self.progress = SVProgressHUDUndefinedProgress;
    self.maskType = hudMaskType;

    //这个方法会移除所有存在的弹窗 所以当  [SVProgressHUD show] 和 [SVProgressHUD showSucc…]连用的时候 就不需要手动调用dismiss
    [self cancelRingLayerAnimation];

    if(![self.class isVisible])
    //最终调用的都是同一个显示的方法,见上面 不自动消失的 底层方法
        [self.class showWithMaskType:self.maskType];
  
    if ([self.imageView respondsToSelector:@selector(setTintColor:)]) {
        self.imageView.tintColor = SVProgressHUDForegroundColor;
    } else {
        image = [self image:image withTintColor:SVProgressHUDForegroundColor];
    }
    self.imageView.image = image;
    self.imageView.hidden = NO;
    
    self.stringLabel.text = string;
    [self updatePosition];
    [self.indefiniteAnimatedView removeFromSuperview];
    
    if(self.maskType != SVProgressHUDMaskTypeNone) {
        self.overlayView.userInteractionEnabled = YES;
        self.accessibilityLabel = string;
        self.isAccessibilityElement = YES;
    } else {
        self.overlayView.userInteractionEnabled = NO;
        self.hudView.accessibilityLabel = string;
        self.hudView.isAccessibilityElement = YES;
    }
    
    UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);
    UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, string);

    //在消息循环里加一个 timer 来调用 dismiss 方法    
    self.fadeOutTimer = [NSTimer timerWithTimeInterval:duration target:self selector:@selector(dismiss) userInfo:nil repeats:NO];
    [[NSRunLoop mainRunLoop] addTimer:self.fadeOutTimer forMode:NSRunLoopCommonModes];
}

显示

显示结构:
从底层到外层

UIControl                   -> 用于操作 maskType 置于当前界面的上层
SVProgressHUD               -> uiview
UIView                      -> 用来展示弹窗
label + image               -> 用来显示具体内容
如下图:左边黄色框是登录界面 从右边蓝色框开始 向右是 UIControl SVProgressHUD UIView (label + image)
5F4CFDED-27BC-42E3-89CB-24A0014748FF.png
正面如下:
9F5BAE2E-FAAE-43C8-8766-6DEAD6F3C24B.png

相关文章

网友评论

  • yifang:我在想 这个hud 添加在UIControl 上,怎么不影响导航栏的点击。 SVProgressHUD好像是直接覆盖在UIControl上~

本文标题:SVProgressHUD 源码略读

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