iOS-随心所欲控制button内image view和title view的位置

刚开始学iOS的时候,一直通过imageInserts 和 titleInserts 设置UIButton的Image以及Label位置,但是它们两个经常互相挤,导致需要特殊效果譬如Image和Label 左右分布,上下分布等功能实现起来颇为麻烦,经常需要调整。而采用UIImage+UILabel + 手势的组合实现起来又过于繁琐,于是研究了下UIButton,写了自定义的 LDButton用来实现对Image 和 Label的位置有特殊要求的功能。 


如何使用LDButton

你只需要按照你的意愿设置 Image 和 Label 的位置即可,如果不设置则会退化成UIButton

//核心设置
btn.imageRect = CGRectMake((btnWidth - 40)/2.0, 50 - 30, 40, 30);
btn.labelRect = CGRectMake(0, 50, btnWidth, 30);

代码实现

核心代码是重写imageRectForContentRect和titleRectForContentRect两个方法,直接返回设置的imageRect 和 labelRect.

问题一:有时需要调整Button的大小,内部的Image的Frame要跟着变

这直接重写ImageRect的set方法即可,调用setNeedsDisplay会重刷imageRectForContentRect方法

- (void)setImageRect:(CGRect)imageRect {
    _imageRect = imageRect;

    [self setNeedsDisplay];
}

问题二:有的时候经常忘记设置imageRect和labelRect,结果直接崩溃了

刚学iOS的时候一直没有找到很好的解决办法,直到我学习了Runtime相关知识,解决方案:没有设置imageRect 和labelRect时,直接返回系统的方法。

@implementation NSObject(Extension)
+ (void)swizzleInstanceMethod:(Class)class originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector
{
  Method swizzledMehtod = class_getInstanceMethod(class, swizzledSelector);
  Method originalMehtod = class_getInstanceMethod(class, originalSelector);
  // 交换2个方法的实现
  method_exchangeImplementations(swizzledMehtod, originalMehtod);
}
@end
+ (void)load
{
  [self swizzleInstanceMethod:NSClassFromString(@"LDButton") originalSelector:@selector(imageRectForContentRect:) swizzledSelector:@selector(ld_imageRectForContentRect:)];
  [self swizzleInstanceMethod:NSClassFromString(@"LDButton") originalSelector:@selector(titleRectForContentRect:) swizzledSelector:@selector(ld_titleRectForContentRect:)];
}
- ( CGRect )ld_imageRectForContentRect:( CGRect )contentRect
{
  //设置了值就返回设置的值,否则用系统的
  if (!CGRectEqualToRect(_imageRect,CGRectZero)) {
    return _imageRect;
  }
  return [self ld_imageRectForContentRect:contentRect];
}
展开阅读全文

没有更多推荐了,返回首页