首先說明一個(gè)需求,如下圖

默認(rèn)顯示.png
上面的文本偷懶的時(shí)候會(huì)這樣布局,可是會(huì)有需求提出需要文本1頂部對(duì)齊,可是又需要底部緊靠下方文本,一般做法就是設(shè)置一個(gè)小的高度,讓文本顯示即可。
針對(duì)于此,我們可以利用runtime重寫兩個(gè)方法,其實(shí)原則上是不建議在分類中重寫父類的方法,入侵性太大了,我們只需重寫之后保持父類方法仍然可用即可。
- (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];
}
使用
頂部對(duì)齊
self.myLabel.verticalStyle = LXVerticalAlignmentTop;

頂部.png
頂部對(duì)齊
self.myLabel.verticalStyle = LXVerticalAlignmentBottom;

底部.png
該分類已被收錄在LXUtils中,可直接pod.