首先说明一个需求,如下图
![](https://img.haomeiwen.com/i1694376/645851c8dc0d3f6b.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;
![](https://img.haomeiwen.com/i1694376/d5dab700f271c370.png)
顶部对齐
self.myLabel.verticalStyle = LXVerticalAlignmentBottom;
![](https://img.haomeiwen.com/i1694376/096d7b267f41bfc5.png)
该分类已被收录在LXUtils中,可直接pod.
网友评论