用runtime修改UITabBarItem的图片大小
废话不多说,直接上代码
```
@interfaceUITabBarItem (XTabBarItem)
@property(nonatomic,assign)CGSizeimageSize;//希望设置的图片大小
@end
#import"UITabBarItem+XTabBarItem.h"
@implementationUITabBarItem (XTabBarItem)
//方法交换
voidexchangeSelector(Class theClass,SELfirstSelector,SELsecondSelector) {
MethodfirstMethod =class_getInstanceMethod(theClass, firstSelector);
MethodsecondMethod =class_getInstanceMethod(theClass, secondSelector);
method_exchangeImplementations(firstMethod, secondMethod);
}
#pragma mark - init
+ (void)load {
exchangeSelector([selfclass],@selector(init),@selector(x_init));
exchangeSelector([selfclass],@selector(initWithCoder:),@selector(x_initWithCoder:));
}
- (instancetype)x_init {
[selfx_init];
return[selfadditional];
}
- (instancetype)x_initWithCoder:(NSCoder*)aDecoder {
[selfx_initWithCoder:aDecoder];
return[selfadditional];
}
- (instancetype)additional {
if(self) {
//寻找button
unsignedinttabBarItemIvarsCount =0;
Ivar*tabBarItemIvars =class_copyIvarList([selfclass], &tabBarItemIvarsCount);
for(unsignedinti =0; i < tabBarItemIvarsCount; i ++) {
IvartabBarItemIvar = tabBarItemIvars[i];
constchar*c_tabBarItemIvar_name =ivar_getName(tabBarItemIvar);
if(!c_tabBarItemIvar_name) {
continue;
}
NSString*tabBarItemIvar_name = [NSStringstringWithUTF8String:c_tabBarItemIvar_name];
if(!tabBarItemIvar_name) {
continue;
}
if([tabBarItemIvar_nameisEqualToString:@"_view"]) {
//因为是懒加载,所以开启KVO监听button的创建
[selfaddObserver:selfforKeyPath:@"view"options:NSKeyValueObservingOptionNewcontext:NULL];
break;
}
}
if(tabBarItemIvars) {
free(tabBarItemIvars);
}
}
returnself;
}
#pragma mark - property
- (void)setImageSize:(CGSize)imageSize {
[selfwillChangeValueForKey:@"imageSize"];
NSValue*value = [NSValuevalue:&imageSizewithObjCType:@encode(CGSize)];
objc_setAssociatedObject(self,_cmd, value,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[selfdidChangeValueForKey:@"imageSize"];
}
- (CGSize)imageSize {
CGSizesize;
NSValue*value =objc_getAssociatedObject(self,@selector(setImageSize:));
if(value) {
[valuegetValue:&size];
}else{
size =CGSizeZero;
[selfsetImageSize:size];
}
returnsize;
}
#pragma mark - KVO
- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context {
if([keyPathisEqualToString:@"view"]) {//button
//马上把KVO移除,因为不再需要用到
[selfremoveObserver:selfforKeyPath:@"view"];
//寻找button,再找button下的imageView
unsignedinttabBarItemIvarsCount =0;
Ivar*tabBarItemIvars =class_copyIvarList([selfclass], &tabBarItemIvarsCount);
for(unsignedinti =0; i < tabBarItemIvarsCount; i ++) {
IvartabBarItemIvar = tabBarItemIvars[i];
constchar*c_tabBarItemIvar_name =ivar_getName(tabBarItemIvar);
if(!c_tabBarItemIvar_name) {
continue;
}
NSString*tabBarItemIvar_name = [NSStringstringWithUTF8String:c_tabBarItemIvar_name];
if(!tabBarItemIvar_name) {
continue;
}
if([tabBarItemIvar_nameisEqualToString:@"_view"]) {
UIControl*tabBarButton =object_getIvar(self, tabBarItemIvar);//它就是button
unsignedinttabBarButtonIvarsCount =0;
Ivar*tabBarButtonIvars =class_copyIvarList([tabBarButtonclass], &tabBarButtonIvarsCount);
BOOLshouldBreak =NO;
for(unsignedintj =0; j < tabBarButtonIvarsCount; j ++) {
IvartabBarButtonIvar = tabBarButtonIvars[j];
constchar*c_tabBarButtonIvar_name =ivar_getName(tabBarButtonIvar);
if(!c_tabBarButtonIvar_name) {
continue;
}
NSString*tabBarButtonIvar_name = [NSStringstringWithUTF8String:c_tabBarButtonIvar_name];
if(!tabBarButtonIvar_name) {
continue;
}
if([tabBarButtonIvar_nameisEqualToString:@"_info"]) {//这货就是imageView了
UIImageView*imageView =object_getIvar(tabBarButton, tabBarButtonIvar);
//用KVO监听imageView的frame变化
[imageViewaddObserver:selfforKeyPath:@"frame"options:NSKeyValueObservingOptionNewcontext:NULL];
shouldBreak =YES;
break;
}
}
if(tabBarButtonIvars) {
free(tabBarButtonIvars);
}
if(shouldBreak) {
break;
}
}
}
if(tabBarItemIvars) {
free(tabBarItemIvars);
}
}elseif([keyPathisEqualToString:@"frame"]) {
//imageView的frame改变了
if(CGSizeEqualToSize(self.imageSize,CGSizeZero)) {
return;
}
//在这里就能把imageView设置为所要设置的大小(imageSize)
UIImageView*imageView = object;
UIControl*button = imageView.superview;
UILabel*label =nil;
for(UIView*subViewinbutton.subviews) {
if([subViewisKindOfClass:NSClassFromString(@"UITabBarButtonLabel")]) {
label = subView;
break;
}
}
if(CGPointEqualToPoint(label.frame.origin,CGPointZero)) {
return;
}
CGFloatwidth =self.imageSize.width;
CGFloatheight =self.imageSize.height;
CGFloatx = (button.frame.size.width- width) /2.0;
CGFloaty = (label.frame.origin.y- height) /2.0;
CGRectframe =CGRectMake(x, y, width, height);
if(CGRectEqualToRect(imageView.frame, frame)) {
return;
}
[imageViewsetFrame:frame];
}
}
@end
```