前言
UIScrollView
有contentInset
这个属性,但是UILabel
没有;Android有,iOS没有。
最近需要用到带内边距的label,所以就结合网上前辈的代码封装了一个,本来我是想弄一个category的,但最终失败了。
代码如下,继承自UILabel
:
.h文件:
#import
@interface EdgeInsetsLabel : UILabel
@property (nonatomic) UIEdgeInsets contentInset;
@end
.m文件:
#import "EdgeInsetsLabel.h"
@implementation EdgeInsetsLabel
- (void)setContentInset:(UIEdgeInsets)contentInset {
_contentInset = contentInset;
NSString *tempString = self.text;
self.text = @"";
self.text = tempString;
}
-(void)drawTextInRect:(CGRect)rect {
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.contentInset)];
}
@end
使用
self.label.contentInset = UIEdgeInsetsMake(0, 20, 0, 20);
代码说明
改变label的inset是在这个方法里面进行的:
-(void)drawTextInRect:(CGRect)rect {
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.contentInset)];
}
这是系统提供的方法:
这个方法不能主动调用,但我们又需要在这个方法中做处理,怎么办?
我实验了一下,改变label的text的时候会回调这个方法。
也就是说,我们可以通过改变label的text的方式来间接调用这个方法。
所以就有了这段奇葩的赋值contentInset的代码:
- (void)setContentInset:(UIEdgeInsets)contentInset {
_contentInset = contentInset;
NSString *tempString = self.text;
self.text = @"";
self.text = tempString;
}
先将label文本清空,再重新赋值text,从而达到改变label的text的效果,最终回调drawTextInRect:
方法。
这样我们给label赋值contentInset的时候就能立即看到效果了。
效果GIF:
对应的代码:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.label = [[EdgeInsetsLabel alloc] initWithFrame:CGRectMake(90, 90, 200, 100)];
[self.view addSubview:self.label];
self.label.text = @"人之初,性本善,我最喜欢吃鸡蛋。人之初,性本善,我最喜欢吃鸡蛋。人之初,性本善,我最喜欢吃鸡蛋。人之初,性本善,我最喜欢吃鸡蛋。";
self.label.numberOfLines = 0;
self.label.backgroundColor = [UIColor orangeColor];
self.label.contentInset = UIEdgeInsetsMake(0, 20, 0, 20);
// 3秒后改变contentInset
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.label.contentInset = UIEdgeInsetsMake(20, 50, 10, 20);
});
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.label.contentInset = UIEdgeInsetsMake(0, 80, 0, 20);
self.label.text = @"因缺思厅";
}
demo
点击获取DEMO
最后
如果你有更好的方法不要吝惜分享啊。
2017年12月28日更新
根据评论区neghao同学的建议,要调用drawTextInRect
这个方法可以通过调用UILabel
的setNeedsDisplay
方法来实现。
所以赋值contentInset就可以改成这样了:
- (void)setContentInset:(UIEdgeInsets)contentInset {
_contentInset = contentInset;
[self setNeedsDisplay];
}
代码已更新到GitHub。
感谢大家的建议。