iOS开发笔记 | 自定义具有内边距的label

iOS开发笔记 | 自定义具有内边距的label_第1张图片
iu

前言

UIScrollViewcontentInset这个属性,但是UILabel没有;Android有,iOS没有。

最近需要用到带内边距的label,所以就结合网上前辈的代码封装了一个,本来我是想弄一个category的,但最终失败了。

iOS开发笔记 | 自定义具有内边距的label_第2张图片

代码如下,继承自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)];
}

这是系统提供的方法:


iOS开发笔记 | 自定义具有内边距的label_第3张图片

这个方法不能主动调用,但我们又需要在这个方法中做处理,怎么办?

我实验了一下,改变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:方法。

iOS开发笔记 | 自定义具有内边距的label_第4张图片
社会社会

这样我们给label赋值contentInset的时候就能立即看到效果了。

效果GIF:

iOS开发笔记 | 自定义具有内边距的label_第5张图片
效果.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这个方法可以通过调用UILabelsetNeedsDisplay方法来实现。

所以赋值contentInset就可以改成这样了:

- (void)setContentInset:(UIEdgeInsets)contentInset {
    _contentInset = contentInset;
    
    [self setNeedsDisplay];
}

代码已更新到GitHub。

感谢大家的建议。

你可能感兴趣的:(iOS开发笔记 | 自定义具有内边距的label)