Closed MoLice closed 3 years ago
在 4.2.2 版本里,为了解决 #1122 ,在 UITabBarItem (QMUIThemeCompatibility)
里对 selectedImage 做了 QMUI 自己的备份。这里预期的执行顺序是 ①→③→②,也即在 setSelectedImage:
后,对最新的 selectedImage
备份了一份,等到访问 getter selectedImage
时再把之前备份的那个对象返回回去。
但实际的执行顺序却是 ①→②→③,也即在 [super setSelectedImage:]
里会先触发一次 [super selectedImage]
,在这里就获取绑定的 selectedImage
,而此时③尚未执行,新的 selectedImage
其实还没绑定到 item 里,所以②拿到的是旧的图片,表现出来就是第二次设置的 selectedImage
无法生效。
4.2.3 里将会修复该问题,在此之前你可以将以下代码替换到本地同名文件内:
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// UITabBarItem.image 会一直保存原始的 image(例如 QMUIThemeImage),但 selectedImage 只会返回 rawImage,这导致了将一个 QMUIThemeImage 设置给 selectedImage 后,主题切换后 selectedImage 无法刷新(因为 UITabBarItem 并没有保存它,保存的是它的 rawImage),所以这里自己保存 image 的引用。
// https://github.com/Tencent/QMUI_iOS/issues/1122
OverrideImplementation([UITabBarItem class], @selector(setSelectedImage:), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) {
return ^(UITabBarItem *selfObject, UIImage *selectedImage) {
// 必须先保存起来再执行 super,因为 setter 的 super 里会触发 getter,如果不先保存,就会导致走到 getter 时拿到的 boundObject 还是旧值
// https://github.com/Tencent/QMUI_iOS/issues/1218
[selfObject qmui_bindObject:selectedImage.qmui_isDynamicImage ? selectedImage : nil forKey:@"UITabBarItem(QMUIThemeCompatibility).selectedImage"];
// call super
void (*originSelectorIMP)(id, SEL, UIImage *);
originSelectorIMP = (void (*)(id, SEL, UIImage *))originalIMPProvider();
originSelectorIMP(selfObject, originCMD, selectedImage);
};
});
OverrideImplementation([UITabBarItem class], @selector(selectedImage), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) {
return ^UIImage *(UITabBarItem *selfObject) {
// call super
UIImage * (*originSelectorIMP)(id, SEL);
originSelectorIMP = (UIImage * (*)(id, SEL))originalIMPProvider();
UIImage *result = originSelectorIMP(selfObject, originCMD);
UIImage *selectedImage = [selfObject qmui_getBoundObjectForKey:@"UITabBarItem(QMUIThemeCompatibility).selectedImage"];
if (selectedImage) {
return selectedImage;
}
return result;
};
});
});
}
@end
Bug 表现 UITabBarItem 只有第一次
setSelectedImage:
有效。如何重现
如以 QMUI Demo 为例,在设置完 selectedImage 后再重新
setSelectedImage:
,选中的图片依然保持第一次设置的值。其他信息