美文网首页iOS Developer
iOS UILabel 添加 edgeInsets 间距

iOS UILabel 添加 edgeInsets 间距

作者: Bug猫 | 来源:发表于2017-07-28 18:37 被阅读351次

    用类别的方式,来实现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

    相关文章

      网友评论

        本文标题:iOS UILabel 添加 edgeInsets 间距

        本文链接:https://www.haomeiwen.com/subject/hwyflxtx.html