iOS Developer

iOS UILabel 添加 edgeInsets 间距

2017-07-28  本文已影响351人  Bug猫

用类别的方式,来实现label的内边距。

UILabel+myEdgeInsets.h

#import@interface UILabel (myEdgeInsets)

@property (nonatomic, assign)UIEdgeInsets edgeInsets;

@end

UILabel+myEdgeInsets.m

#import "UILabel+myEdgeInsets.h"

@implementation UILabel (myEdgeInsets)

// 钩子

+ (void)load {

method_exchangeImplementations(class_getInstanceMethod(self.class, @selector(textRectForBounds:limitedToNumberOfLines:)),

class_getInstanceMethod(self.class, @selector(sxt_textRectForBounds:sxt_limitedToNumberOfLines:)));

method_exchangeImplementations(class_getInstanceMethod(self.class, @selector(drawTextInRect:)),

class_getInstanceMethod(self.class, @selector(sxt_drawTextInRect:)));

}

//runTime 关联

- (void)setEdgeInsets:(UIEdgeInsets)edgeInsets{

//id  不让放struct 类型

NSArray * arr = @[@(edgeInsets.top),@(edgeInsets.left),@(edgeInsets.bottom),@(edgeInsets.right)];

objc_setAssociatedObject(self, @selector(edgeInsets), arr, OBJC_ASSOCIATION_RETAIN);

}

- (UIEdgeInsets)edgeInsets{

NSArray * arr = objc_getAssociatedObject(self, @selector(edgeInsets));

return UIEdgeInsetsMake([arr[0] floatValue], [arr[1] floatValue], [arr[2] floatValue], [arr[3] floatValue]);

}

#pragma mark -

// 修改绘制文字的区域,edgeInsets增加bounds

-(CGRect)sxt_textRectForBounds:(CGRect)bounds sxt_limitedToNumberOfLines:(NSInteger)numberOfLines{

/*

注意传入的UIEdgeInsetsInsetRect(bounds, self.edgeInsets),bounds是真正的绘图区域

CGRect rect = [super textRectForBounds: limitedToNumberOfLines:numberOfLines];

类别中不能使用 super  用黑魔法替换方法

*/

CGRect rect = [self sxt_textRectForBounds:UIEdgeInsetsInsetRect(bounds,self.edgeInsets) sxt_limitedToNumberOfLines:numberOfLines];

//根据edgeInsets,修改绘制文字的bounds

rect.origin.x -= self.edgeInsets.left;

rect.origin.y -= self.edgeInsets.top;

rect.size.width += self.edgeInsets.left + self.edgeInsets.right;

rect.size.height += self.edgeInsets.top + self.edgeInsets.bottom;

return rect;

}

//绘制文字

- (void)sxt_drawTextInRect:(CGRect)rect{

//令绘制区域为原始区域,增加的内边距区域不绘制

[self sxt_drawTextInRect:UIEdgeInsetsInsetRect(rect, self.edgeInsets)];

}

@end

过程中遇到了几个问题:

1.类别中不能添加成员属性

解决:用runtime 关联的方式 实现set get方法。

2.用runtime  objc_setAssociatedObject(<#id object#>, <#const void *key#>, <#id value#>, <#objc_AssociationPolicy policy#>) 中的id 放不了UIEdgeInsets(struct 类型)

解决:存关联的时候转化成数组 ,取的时候再转化回来。

3.类别中不能用 super(重写方法时候要用super)

解决:用method_exchangeImplementations(黑魔法    钩子)替换方法的调用。(就相当于把self调用这个方法当做了super,然后在自己替换的方法中写 添加边距)

希望能对你有所帮助,欢迎指点。:-D

上一篇下一篇

猜你喜欢

热点阅读