美文网首页将来跳槽用
iOS 利用runtime修改UILabel的默认显示文本方式

iOS 利用runtime修改UILabel的默认显示文本方式

作者: 雪_晟 | 来源:发表于2017-11-18 16:52 被阅读182次

首先说明一个需求,如下图

默认显示.png
上面的文本偷懒的时候会这样布局,可是会有需求提出需要文本1顶部对齐,可是又需要底部紧靠下方文本,一般做法就是设置一个小的高度,让文本显示即可。
针对于此,我们可以利用runtime重写两个方法,其实原则上是不建议在分类中重写父类的方法,入侵性太大了,我们只需重写之后保持父类方法仍然可用即可。
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines;- (void)drawTextInRect:(CGRect)rect;

利用runtime给分类增加属性。

typedef enum
{
    
     LXVerticalAlignmentMiddle = 0, // default
    LXVerticalAlignmentTop,
    LXVerticalAlignmentBottom,
} LXVerticalAlignment;
@interface UILabel (LXVerticalStyle)
@property(nonatomic,assign)LXVerticalAlignment verticalStyle;
-(void)setVerticalStyle:(LXVerticalAlignment)verticalStyle{
    
    objc_setAssociatedObject(self, &style, @(verticalStyle), OBJC_ASSOCIATION_ASSIGN);
    [self setNeedsDisplay];
}
-(LXVerticalAlignment)verticalStyle{
   id value =  objc_getAssociatedObject(self, &style);
    return [value intValue];
}

接下来就是交换方法,重写布局。

交换方法

+(void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        Class class =   objc_getClass("UILabel");
        [class methodSwizzlingWithOriginalSelector:@selector(textRectForBounds:limitedToNumberOfLines:) bySwizzledSelector:@selector(LXTextRectForBounds:limitedToNumberOfLines:) ];
        
          [class methodSwizzlingWithOriginalSelector:@selector(drawTextInRect:) bySwizzledSelector:@selector(LXDrawTextInRect:) ];
        
    });
}

重写布局

-(CGRect)LXTextRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines{
    CGRect textRect = [self LXTextRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
    switch (self.verticalStyle) {
        case LXVerticalAlignmentTop:
            textRect.origin.y = bounds.origin.y;
            break;
        case LXVerticalAlignmentBottom:
            textRect.origin.y = bounds.origin.y + bounds.size.height - textRect.size.height;
            break;
        case LXVerticalAlignmentMiddle:
            // Fall through.
        default:
            textRect.origin.y = bounds.origin.y + (bounds.size.height - textRect.size.height) / 2.0;
    }
    return textRect;
}

-(void)LXDrawTextInRect:(CGRect)requestedRect {
    CGRect actualRect = [self textRectForBounds:requestedRect limitedToNumberOfLines:self.numberOfLines];
    [self LXDrawTextInRect:actualRect];
}

使用

顶部对齐
self.myLabel.verticalStyle = LXVerticalAlignmentTop;

顶部.png

顶部对齐
self.myLabel.verticalStyle = LXVerticalAlignmentBottom;

底部.png

该分类已被收录在LXUtils中,可直接pod.

相关文章

网友评论

    本文标题:iOS 利用runtime修改UILabel的默认显示文本方式

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