本文主要利用Objective-c 的category 和runtime 特性定制UIButton的布局驹沿。UIButton 的圖片和標(biāo)題布局在下面兩個方法中返回正確的rect即可扔仓。
-(CGRect)titleRectForContentRect:(CGRect)contentRect;
-(CGRect)imageRectForContentRect:(CGRect)contentRect;
可以繼承父類重寫方法即可。但在這里沒有用到繼承仍律,而是在Category中使用MethodSwizzle實現(xiàn)拘悦。
+load 方法會在實例化對象之前調(diào)用诈豌,且在main函數(shù)之前。常常用來 method swizzle云矫。Category無法添加實例變量膳沽,使用了關(guān)聯(lián)對象。
+ (void)load {
Method imageOriginalMethod = class_getInstanceMethod([self class], @selector(imageRectForContentRect:));
Method imageSwizzledMethod = class_getInstanceMethod([self class], @selector(sd_imageRectForContentRect:));
method_exchangeImplementations(imageOriginalMethod, imageSwizzledMethod);
}
- (void)setImageRect:(CGRect)imageRect {
NSValue *value = [NSValue valueWithCGRect:imageRect];
objc_setAssociatedObject(self, @selector(imageRect), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (CGRect)imageRect {
NSValue *value = objc_getAssociatedObject(self, @selector(imageRect));
return [value CGRectValue];
}
算了 让禀,啥也不想說了挑社。看代碼巡揍。設(shè)置title的位置和這玩意兒很像痛阻。
- (CGRect)sd_imageRectForContentRect:(CGRect)contentRect {
if (!CGRectIsEmpty(self.imageRect) && !CGRectEqualToRect(self.imageRect, CGRectZero)) {
return self.imageRect;
}
CGRect imgRect = [self sd_imageRectForContentRect:contentRect];
CGRect titRect = [self sd_titleRectForContentRect:contentRect];
if (self.buttonStyle == SDButtonStyleTitleLeft) {
imgRect.origin.x = CGRectGetMaxX(titRect) - CGRectGetWidth(imgRect);
return imgRect;
}
if (self.buttonStyle == SDButtonStyleTitleDown) {
imgRect.origin.x = (CGRectGetWidth(contentRect) - CGRectGetWidth(imgRect))/2.f;
imgRect.origin.y = (CGRectGetHeight(contentRect) - CGRectGetHeight(titRect) - CGRectGetHeight(imgRect) ) /2.f;
return imgRect;
}
if (self.buttonStyle == SDButtonStyleTitleUp) {
imgRect.origin.x = (CGRectGetWidth(contentRect) - CGRectGetWidth(imgRect))/2.f;
imgRect.origin.y = (CGRectGetHeight(contentRect) + CGRectGetHeight(titRect) - CGRectGetHeight(imgRect))/2.f;
return imgRect;
}
return imgRect;
}
使用時,可以直接計算好兩者的位置腮敌,設(shè)置imageRect和titleRect即可阱当。如果你比我還懶,也可以設(shè)置buttonStyle糜工。Rect的優(yōu)先級高于buttonStyle弊添,設(shè)置前者之后,后者無效捌木。
有興趣的在這里拿[demo] [id]表箭。文筆粗爛,懶癌晚期钮莲。謝謝。
[id]: https://github.com/doudouapp/ButtonStyle.git