實現一個在autolayout下有寬度約束后,自動確定高度的view


我曾經遇到過一個問題:需要實現一個自定義的label(類似於UILabel),同時需要兼顧UILabel的大小自適應的特性。這個label通常寬度是固定的,通過autolayout指定其寬度約束,但不指定高度,讓其根據內容自適應。

 

我們知道UIView的方法intrinsicContentSize可以幫助我們確定視圖在autolayout下的大小,從而避免我們去設置其寬高的約束。於是我采用了這樣的解決方案:將label的寬度作為其屬性,使用前我必須指定label的寬度,然后label本身通過其寬度屬性確定高度。然而這個方法不太方便,因為寬度有時需要我們去計算,比如說它是屏幕寬度減去某個值。然而我是一個足夠懶的程序員,不想每次去手動設置寬度。

 

后來思路終於有了,雖然不知道這是否是最佳方法,但至少解決了問題。在autolayout布局完成后,我們就可以知道視圖的最終寬度了。這時我們可以通過

invalidateIntrinsicContentSize方法重新計算視圖的大小。

 

代碼如下:

1 @interface MyLabel : UIView
2 
3 @property (nonatomic, strong) UIFont *font;
4 @property (nonatomic, strong) NSString *text;
5 
6 @end

 

 1 @interface MyLabel ()
 2 
 3 @property (nonatomic, strong) UIFont *defaultFont;
 4 
 5 @end
 6 
 7 @implementation MyLabel
 8 
 9 - (instancetype)init
10 {
11     self = [super init];
12     if (self) {
13         self.defaultFont = [UIFont systemFontOfSize:16];
14     }
15     return self;
16 }
17 
18 - (void)setText:(NSString *)text
19 {
20     _text = text;
21     [self setNeedsLayout];
22     [self setNeedsDisplay];
23 }
24 
25 - (void)layoutSubviews
26 {
27     [self invalidateIntrinsicContentSize]; // 在布局的時候強制重新計算大小
28     [super layoutSubviews];
29 }
30 
31 - (CGSize)sizeThatFits:(CGSize)size
32 {
33     UIFont *font = self.font ? self.font : self.defaultFont;
34     size.width = ceil(size.width); // 避免單行文本二次計算時被錯誤地計算為兩行高度
35     if (size.width > 0) {
36         return [self.text boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil].size;
37     } else { // 此處是為了兼容不設寬度的情況(單行文本)
38         return [self.text sizeWithAttributes:@{NSFontAttributeName:font}];
39     }
40 }
41 
42 - (CGSize)intrinsicContentSize
43 {
44     return [self sizeThatFits:CGSizeMake(CGRectGetWidth(self.bounds), CGFLOAT_MAX)];
45 }
46 
47 - (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize
48 {
49     return [self sizeThatFits:targetSize];
50 }
51 
52 - (void)drawRect:(CGRect)rect
53 {
54     UIFont *font = self.font ? self.font : self.defaultFont;
55     [self.text drawInRect:rect withAttributes:@{NSFontAttributeName:font}];
56 }
57 
58 @end

 

讓我們來測試一下:

 1     MyLabel *label = [MyLabel new];
 2     label.backgroundColor = [UIColor yellowColor];
 3     [self.view addSubview:label];
 4     [label mas_makeConstraints:^(MASConstraintMaker *make) { // 這里並沒設高度約束
 5         make.left.mas_equalTo(10);
 6         make.top.mas_equalTo(100);
 7         make.width.mas_lessThanOrEqualTo(100);
 8     }];
 9 
10     label.text = @"this is a long text. this is a long text.";

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM