美文网首页iOS
读 MBProgressHUD 感

读 MBProgressHUD 感

作者: 天空中的球 | 来源:发表于2016-07-28 18:38 被阅读179次

    话说,MBProgressHUD 是我接触iOS的第一个第三方的轮子,感觉还是很有感情的,一直一来也没好好看看里面,下面是大致看完后记录的几个点。

    • 利用KVO 刷新
    • 各种宏的巧用
    • 永远保证UIView 在主线程中进行动作

    同时在想,MBProgressHUD 也有一个使用上的不方便是,弹出短时间内的提示框的时候,不能点击其他操作,这个很多时候是很不方便的。

    一、利用 KVO 刷新
    #pragma mark - KVO
    - (void)registerForKVO {
        for (NSString *keyPath in [self observableKeypaths]) {
            [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL];
        }
    }
    
    - (void)unregisterFromKVO {
        for (NSString *keyPath in [self observableKeypaths]) {
            [self removeObserver:self forKeyPath:keyPath];
        }
    }
    
    - (NSArray *)observableKeypaths {
        return [NSArray arrayWithObjects:@"mode", @"customView", @"labelText", @"labelFont", @"labelColor",
                @"detailsLabelText", @"detailsLabelFont", @"detailsLabelColor", @"progress", @"activityIndicatorColor", nil];
    }
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
        if (![NSThread isMainThread]) {
            [self performSelectorOnMainThread:@selector(updateUIForKeypath:) withObject:keyPath waitUntilDone:NO];
        } else {
            [self updateUIForKeypath:keyPath];
        }
    }
    
    - (void)updateUIForKeypath:(NSString *)keyPath {
        if ([keyPath isEqualToString:@"mode"] || [keyPath isEqualToString:@"customView"] ||
            [keyPath isEqualToString:@"activityIndicatorColor"]) {
            [self updateIndicators];
        } else if ([keyPath isEqualToString:@"labelText"]) {
            label.text = self.labelText;
        } else if ([keyPath isEqualToString:@"labelFont"]) {
            label.font = self.labelFont;
        } else if ([keyPath isEqualToString:@"labelColor"]) {
            label.textColor = self.labelColor;
        } else if ([keyPath isEqualToString:@"detailsLabelText"]) {
            detailsLabel.text = self.detailsLabelText;
        } else if ([keyPath isEqualToString:@"detailsLabelFont"]) {
            detailsLabel.font = self.detailsLabelFont;
        } else if ([keyPath isEqualToString:@"detailsLabelColor"]) {
            detailsLabel.textColor = self.detailsLabelColor;
        } else if ([keyPath isEqualToString:@"progress"]) {
            if ([indicator respondsToSelector:@selector(setProgress:)]) {
                [(id)indicator setValue:@(progress) forKey:@"progress"];
            }
            return;
        }
        [self setNeedsLayout];
        [self setNeedsDisplay];
    }
    

    获取属性,用KVO刷新,很巧妙,很直接,这个可以学习。

    - (NSArray *)observableKeypaths;
    
    二、 各种宏的巧用

    区分ARC 的情况

    #ifndef MB_INSTANCETYPE
    #if __has_feature(objc_instancetype)
        #define MB_INSTANCETYPE instancetype
    #else
        #define MB_INSTANCETYPE id
    #endif
    #endif
    
    #ifndef MB_STRONG
    #if __has_feature(objc_arc)
        #define MB_STRONG strong
    #else
        #define MB_STRONG retain
    #endif
    #endif
    
    #ifndef MB_WEAK
    #if __has_feature(objc_arc_weak)
        #define MB_WEAK weak
    #elif __has_feature(objc_arc)
        #define MB_WEAK unsafe_unretained
    #else
        #define MB_WEAK assign
    #endif
    #endif
    

    区分不同版本的

    #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000
        #define MBLabelAlignmentCenter NSTextAlignmentCenter
    #else
        #define MBLabelAlignmentCenter UITextAlignmentCenter
    #endif
    
    #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
        #define MB_TEXTSIZE(text, font) [text length] > 0 ? [text \
            sizeWithAttributes:@{NSFontAttributeName:font}] : CGSizeZero;
    #else
        #define MB_TEXTSIZE(text, font) [text length] > 0 ? [text sizeWithFont:font] : CGSizeZero;
    #endif
    
    #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
        #define MB_MULTILINE_TEXTSIZE(text, font, maxSize, mode) [text length] > 0 ? [text \
            boundingRectWithSize:maxSize options:(NSStringDrawingUsesLineFragmentOrigin) \
            attributes:@{NSFontAttributeName:font} context:nil].size : CGSizeZero;
    #else
        #define MB_MULTILINE_TEXTSIZE(text, font, maxSize, mode) [text length] > 0 ? [text \
            sizeWithFont:font constrainedToSize:maxSize lineBreakMode:mode] : CGSizeZero;
    #endif
    
    

    哎,想想还是顺便放到我另一个笔记中iOS 中常用宏,判断文字宽度不同版本的两者还是很实用的。

    三、 永远保证UIView 在主线程中进行动作

    • show 时的判断
     NSAssert([NSThread isMainThread], @"MBProgressHUD needs to be accessed on the main thread.");
    
    
    • KVO 刷新时的判断
     if (![NSThread isMainThread]) {
            [self performSelectorOnMainThread:@selector(updateUIForKeypath:) withObject:keyPath waitUntilDone:NO];
        } else {
            [self updateUIForKeypath:keyPath];
        }
    

    另外注意, 直接取消一个对象在当前Run Loop中的所有未执行的performSelector:withObject:afterDelay:方法所产生的Selector Sources

    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    

    总的来说,其实在里面还是有多细节可以挖掘的,看我们的关注点吧

    - (void)layoutSubviews;
    - (void)drawRect:(CGRect)rect;

    像上述两个方法中有很多可以去发现,同时要进行一些额外的操作也可以在这里面进行添加或修改。

    像之前想的问题,弹出短时间内的提示框的时候,不能点击其他操作, 也许一个简单的交互就可以实现:

    hud.userInteractionEnabled = NO;
    

    又或是通过设置添加一个取消按钮也可以,当然这样更好。

    而真正使用MBProgressHUD 还是很简单的,直接看一个github中的源码的Demo 基本都会啦。

    备注下:以上是 Version 0.9.2中的一些点,而最新版本中已经有很多不同啦,可以再次学习,😄

    相关文章

      网友评论

        本文标题:读 MBProgressHUD 感

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