UI进价iOS开发进阶ios实用开发技巧

UIButton 使用Category 自定义图片和标题位置

2016-11-29  本文已影响122人  泰好笑勒

本文主要利用Objective-c 的category 和runtime 特性定制UIButton的布局。UIButton 的图片和标题布局在下面两个方法中返回正确的rect即可。
-(CGRect)titleRectForContentRect:(CGRect)contentRect;
-(CGRect)imageRectForContentRect:(CGRect)contentRect;
可以继承父类重写方法即可。但在这里没有用到继承,而是在Category中使用MethodSwizzle实现。

+load 方法会在实例化对象之前调用,且在main函数之前。常常用来 method swizzle。Category无法添加实例变量,使用了关联对象。

+ (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];
}

算了 ,啥也不想说了。看代码。设置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;
}

使用时,可以直接计算好两者的位置,设置imageRect和titleRect即可。如果你比我还懒,也可以设置buttonStyle。Rect的优先级高于buttonStyle,设置前者之后,后者无效。

有兴趣的在这里拿[demo] [id]。文笔粗烂,懒癌晚期。谢谢。
[id]: https://github.com/doudouapp/ButtonStyle.git

上一篇 下一篇

猜你喜欢

热点阅读