話說(shuō),MBProgressHUD 是我接觸iOS的第一個(gè)第三方的輪子属划,感覺還是很有感情的诅蝶,一直一來(lái)也沒好好看看里面,下面是大致看完后記錄的幾個(gè)點(diǎn)桑包。
- 利用KVO 刷新
- 各種宏的巧用
- 永遠(yuǎn)保證UIView 在主線程中進(jìn)行動(dòng)作
同時(shí)在想南蓬,MBProgressHUD 也有一個(gè)使用上的不方便是,彈出短時(shí)間內(nèi)的提示框的時(shí)候哑了,不能點(diǎn)擊其他操作赘方,這個(gè)很多時(shí)候是很不方便的。
一弱左、利用 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刷新窄陡,很巧妙,很直接拆火,這個(gè)可以學(xué)習(xí)跳夭。
- (NSArray *)observableKeypaths涂圆;
二、 各種宏的巧用
區(qū)分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
區(qū)分不同版本的
#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
哎币叹,想想還是順便放到我另一個(gè)筆記中iOS 中常用宏润歉,判斷文字寬度不同版本的兩者還是很實(shí)用的。
三颈抚、 永遠(yuǎn)保證UIView 在主線程中進(jìn)行動(dòng)作
- show 時(shí)的判斷
NSAssert([NSThread isMainThread], @"MBProgressHUD needs to be accessed on the main thread.");
- KVO 刷新時(shí)的判斷
if (![NSThread isMainThread]) {
[self performSelectorOnMainThread:@selector(updateUIForKeypath:) withObject:keyPath waitUntilDone:NO];
} else {
[self updateUIForKeypath:keyPath];
}
另外注意, 直接取消一個(gè)對(duì)象在當(dāng)前Run Loop中的所有未執(zhí)行的performSelector:withObject:afterDelay:
方法所產(chǎn)生的Selector Sources
踩衩。
[NSObject cancelPreviousPerformRequestsWithTarget:self];
總的來(lái)說(shuō),其實(shí)在里面還是有多細(xì)節(jié)可以挖掘的贩汉,看我們的關(guān)注點(diǎn)吧
- (void)layoutSubviews;
- (void)drawRect:(CGRect)rect;
像上述兩個(gè)方法中有很多可以去發(fā)現(xiàn)驱富,同時(shí)要進(jìn)行一些額外的操作也可以在這里面進(jìn)行添加或修改。
像之前想的問(wèn)題雾鬼,彈出短時(shí)間內(nèi)的提示框的時(shí)候萌朱,不能點(diǎn)擊其他操作, 也許一個(gè)簡(jiǎn)單的交互就可以實(shí)現(xiàn):
hud.userInteractionEnabled = NO;
又或是通過(guò)設(shè)置添加一個(gè)取消按鈕也可以宴树,當(dāng)然這樣更好策菜。
而真正使用MBProgressHUD 還是很簡(jiǎn)單的,直接看一個(gè)github中的源碼的Demo 基本都會(huì)啦酒贬。