iOSLabel自适应高度实现

2021-09-10  本文已影响0人  数字d

需求:根据服务端返回的字符串数据来展示Label

1.label行数根据字符串长度来增加,默认展示行数小于等于三行
2.label需要展示在一个灰色背景中,label的frame发生变化,灰色背景的frame也发生变化
3.label如果超出三行,第三行尾部省略...,并在灰色背景底部添加一个"显示全部的"按钮
4.点击显示全部,Label行数根据实际展示,不进行折叠并展示另外一个按钮"收起"
5.点击收起,Label重新折叠成三行

效果

1 2 3

步骤:

使用textField模拟服务端返回的字符串,点击蓝色Label模拟开始展示Label和灰色背景view,调试之后第二次输入需要重新运行

核心代码:

1.动态计算label的高度

-(CGFloat)caculateNeedHeightWithString:(NSString *)inputString {
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, Screen_Width - 30 - 22, 0)];
    label.text = inputString;
    label.font = [UIFont systemFontOfSize:11];
    label.numberOfLines = 0;
    [label sizeToFit];
    CGFloat height = label.frame.size.height;
    return height;
}
  1. 根据高度和打印结果估算行数,影响行数的因素是字体大小,Label的初始宽度,textField中的输入监听和一些常规信息展示,如果行数超过三行标记extend为YES
    [[self.textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
        CGFloat height = [self caculateNeedHeightWithString:x];
        NSLog(@"%f",height);
        if (height < 15) {
            NSLog(@"1行");
            weakSelf.minHeight = height + 2;
            weakSelf.maxHeight = height + 2;
            weakSelf.seeTotalLab.hidden = YES;
            weakSelf.seezoomLab.hidden = YES;
            weakSelf.lineNeed = 1;
        }else if (height < 30){
            NSLog(@"2行");
            weakSelf.minHeight = height + 2;
            weakSelf.maxHeight = height + 2;
            weakSelf.seeTotalLab.hidden = YES;
            weakSelf.seezoomLab.hidden = YES;
            weakSelf.lineNeed = 2;
        }else if (height < 45){
            NSLog(@"3行");
            weakSelf.minHeight = height + 2;
            weakSelf.maxHeight = height + 2;
            weakSelf.seeTotalLab.hidden = YES;
            weakSelf.seezoomLab.hidden = YES;
            weakSelf.lineNeed = 3;
        }else{
            weakSelf.extend = YES;
            weakSelf.lineNeed = height / 13;
            NSLog(@"4行或者4行多 %ld",(long)weakSelf.lineNeed);
            weakSelf.minHeight = 40;
            weakSelf.maxHeight = height + 2;
        }
        
        weakSelf.lineLab.text = [NSString stringWithFormat:@"总共 %ld行 现在占用实际高度是 %f   +  %ld",(long)weakSelf.lineNeed,height, (weakSelf.lineNeed - 1) * 5];
        
        
    }];

3.蓝色文字的label的实现和点击事件的处理,将grayBgview展示在view上

-(UILabel *)clickLab {
    if (_clickLab == nil) {
        _clickLab = [[UILabel alloc] initWithFrame:CGRectMake(0, 160, Screen_Width, 40)];
        _clickLab.text = @"点击我之后,grayview和infolabel展示在self.view上";
        _clickLab.textAlignment = NSTextAlignmentCenter;
        _clickLab.font = [UIFont boldSystemFontOfSize:15];
        _clickLab.adjustsFontSizeToFitWidth = YES;
        _clickLab.textColor = [UIColor blueColor];
        _clickLab.userInteractionEnabled = YES;
        WS(weakSelf);
        UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] init];
        [[tap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
            [weakSelf.view addSubview:self.bgGrayView];
            [weakSelf.textField resignFirstResponder];
        }];
        [_clickLab addGestureRecognizer:tap];
        
    }
    return _clickLab;
}

4.查看全部的按钮(UILabel)事件监听

-(UILabel *)seeTotalLab {
    if (_seeTotalLab == nil) {
        _seeTotalLab = [[UILabel alloc] init];
        _seeTotalLab.text = @"查看全部";
        _seeTotalLab.textAlignment = NSTextAlignmentRight;
        _seeTotalLab.font = [UIFont systemFontOfSize:11];
        _seeTotalLab.textColor = [UIColor blueColor];
        _seeTotalLab.userInteractionEnabled = YES;
        UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] init];
        WS(weakSelf);
        [[tap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
            weakSelf.bgGrayView.frame = CGRectMake(weakSelf.bgGrayView.frame.origin.x, weakSelf.bgGrayView.frame.origin.y, weakSelf.bgGrayView.frame.size.width, _maxHeight + 20 + 18 + (self.lineNeed - 1) * 5);
            weakSelf.infoLab.numberOfLines = 0;
            weakSelf.seeTotalLab.hidden = YES;
            weakSelf.seezoomLab.hidden = NO;
        }];
        [_seeTotalLab addGestureRecognizer:tap];
    }
    return _seeTotalLab;
}

5.收起的按钮(UILabel)实现和事件监听

-(UILabel *)seezoomLab {
    if (_seezoomLab == nil) {
        _seezoomLab = [[UILabel alloc] init];
        _seezoomLab.text = @"收起";
        _seezoomLab.textAlignment = NSTextAlignmentRight;
        _seezoomLab.font = [UIFont systemFontOfSize:11];
        _seezoomLab.textColor = [UIColor blueColor];
        _seezoomLab.userInteractionEnabled = YES;
        WS(weakSelf);
        UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] init];
        [[tap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
            weakSelf.bgGrayView.frame = CGRectMake(weakSelf.bgGrayView.frame.origin.x, weakSelf.bgGrayView.frame.origin.y, weakSelf.bgGrayView.frame.size.width, _minHeight + 20 + 18 + (3 - 1) * 5);
            weakSelf.infoLab.numberOfLines = 3;
            weakSelf.seeTotalLab.hidden = NO;
            weakSelf.seezoomLab.hidden = YES;
        }];
        [_seezoomLab addGestureRecognizer:tap];
        
    }
    return _seezoomLab;
}

6.\color{red}{infoLabel中的行间距实现和infoLabel中的到三行以后尾部显示...的省略方式实现}

-(UILabel *)infoLab {
    if (_infoLab == nil) {
        _infoLab = [[UILabel alloc] init];
//        _infoLab.text = self.textField.text;
        _infoLab.numberOfLines = 3;
//        _infoLab.backgroundColor = [UIColor blueColor];
        _infoLab.textAlignment = NSTextAlignmentLeft;
        _infoLab.font = [UIFont systemFontOfSize:11];
        _infoLab.textColor = [UIColor blackColor];
        NSMutableParagraphStyle  *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        // 行间距设置为5
        [paragraphStyle  setLineSpacing:5];
        [paragraphStyle setLineBreakMode:NSLineBreakByTruncatingTail];
        NSString  *testString = self.textField.text;
        NSMutableAttributedString  *setString = [[NSMutableAttributedString alloc] initWithString:testString];
        [setString  addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [testString length])];
        // 设置Label要显示的text
        [_infoLab  setAttributedText:setString];
        _infoLab.backgroundColor = [UIColor yellowColor];
    }
    return _infoLab;
}

因为有时候要用到这种计算高度且加限制最小行数的折叠需求,干脆整理出来单独实现,viewcontroller中所有的代码

//
//  ViewController.m
//  raceme
//
//  Created by mac on 2021/9/3.
//

#import "ViewController.h"

@interface ViewController ()
@property(nonatomic,strong)UITextField * textField;
@property(nonatomic,strong)UILabel * clickLab;
@property(nonatomic,strong)UIView * bgGrayView;
@property(nonatomic,strong)UILabel * infoLab;
@property(nonatomic,strong)UILabel * seeTotalLab;
@property(nonatomic,strong)UILabel * seezoomLab;
@property(nonatomic,strong)UILabel * lineLab;
@property(nonatomic,assign)CGFloat  minHeight;
@property(nonatomic,assign)CGFloat  maxHeight;
@property(nonatomic,assign)NSInteger lineNeed;
@property(nonatomic,assign)BOOL extend;
@end


@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.textField];
    [self.view addSubview:self.clickLab];
    [self.view addSubview:self.lineLab];
    _extend = NO;
    WS(weakSelf);
    [[self.textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
        CGFloat height = [self caculateNeedHeightWithString:x];
        NSLog(@"%f",height);
        if (height < 15) {
            NSLog(@"1行");
            weakSelf.minHeight = height + 2;
            weakSelf.maxHeight = height + 2;
            weakSelf.seeTotalLab.hidden = YES;
            weakSelf.seezoomLab.hidden = YES;
            weakSelf.lineNeed = 1;
        }else if (height < 30){
            NSLog(@"2行");
            weakSelf.minHeight = height + 2;
            weakSelf.maxHeight = height + 2;
            weakSelf.seeTotalLab.hidden = YES;
            weakSelf.seezoomLab.hidden = YES;
            weakSelf.lineNeed = 2;
        }else if (height < 45){
            NSLog(@"3行");
            weakSelf.minHeight = height + 2;
            weakSelf.maxHeight = height + 2;
            weakSelf.seeTotalLab.hidden = YES;
            weakSelf.seezoomLab.hidden = YES;
            weakSelf.lineNeed = 3;
        }else{
            weakSelf.extend = YES;
            weakSelf.lineNeed = height / 13;
            NSLog(@"4行或者4行多 %ld",(long)weakSelf.lineNeed);
            weakSelf.minHeight = 40;
            weakSelf.maxHeight = height + 2;
        }
        
        weakSelf.lineLab.text = [NSString stringWithFormat:@"总共 %ld行 现在占用实际高度是 %f   +  %ld",(long)weakSelf.lineNeed,height, (weakSelf.lineNeed - 1) * 5];
        
        
    }];
    
    
    
    
    
}

-(UITextField * )textField {
    if (_textField == nil) {
        _textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 88, Screen_Width - 20, 45)];
        _textField.placeholder = @"输入文字内容吧";
        _textField.textAlignment = NSTextAlignmentCenter;
        _textField.font = [UIFont systemFontOfSize:11];
        _textField.backgroundColor = [UIColor groupTableViewBackgroundColor];
        _textField.textColor = [UIColor blackColor];
    }
    return _textField;
}

-(UILabel *)clickLab {
    if (_clickLab == nil) {
        _clickLab = [[UILabel alloc] initWithFrame:CGRectMake(0, 160, Screen_Width, 40)];
        _clickLab.text = @"点击我之后,grayview和infolabel展示在self.view上";
        _clickLab.textAlignment = NSTextAlignmentCenter;
        _clickLab.font = [UIFont boldSystemFontOfSize:15];
        _clickLab.adjustsFontSizeToFitWidth = YES;
        _clickLab.textColor = [UIColor blueColor];
        _clickLab.userInteractionEnabled = YES;
        WS(weakSelf);
        UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] init];
        [[tap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
            [weakSelf.view addSubview:self.bgGrayView];
            [weakSelf.textField resignFirstResponder];
        }];
        [_clickLab addGestureRecognizer:tap];
        
    }
    return _clickLab;
}


-(CGFloat)caculateNeedHeightWithString:(NSString *)inputString {
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, Screen_Width - 30 - 22, 0)];
    label.text = inputString;
    label.font = [UIFont systemFontOfSize:11];
    label.numberOfLines = 0;
    [label sizeToFit];
    CGFloat height = label.frame.size.height;
    return height;
}


-(UIView *)bgGrayView {
    if (_bgGrayView == nil) {
        CGFloat totalBgHeight;
        if (_extend) {
            totalBgHeight = _minHeight + 20 + (3 - 1) * 5;
            totalBgHeight += 22;
        }else {
            totalBgHeight = _minHeight + 20 + (self.lineNeed - 1) * 5;
        }
        _bgGrayView = [[UIView alloc] initWithFrame:CGRectMake(15, 200, Screen_Width - 30, totalBgHeight)];
        _bgGrayView.backgroundColor = [UIColor groupTableViewBackgroundColor];
        [_bgGrayView addSubview:self.infoLab];
        [self.infoLab mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(_bgGrayView.mas_left).offset(11);
            make.right.equalTo(_bgGrayView.mas_right).offset(-11);
            make.height.greaterThanOrEqualTo(@10);
            make.top.equalTo(_bgGrayView.mas_top).offset(10);
        }];
        [_bgGrayView addSubview:self.seeTotalLab];
        [_bgGrayView addSubview:self.seezoomLab];
        
        [self.seeTotalLab mas_makeConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(_bgGrayView.mas_right).offset(-10.5);
            make.width.equalTo(@100);
            make.height.equalTo(@22);
            make.bottom.equalTo(_bgGrayView.mas_bottom).offset(-10);
        }];
        self.seeTotalLab.hidden = !_extend;
        
        [self.seezoomLab mas_makeConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(_bgGrayView.mas_right).offset(-10.5);
            make.width.equalTo(@70);
            make.height.equalTo(@22);
            make.bottom.equalTo(_bgGrayView.mas_bottom).offset(-10);
        }];
        self.seezoomLab.hidden = YES;
        
    }
    return _bgGrayView;
}

-(UILabel *)infoLab {
    if (_infoLab == nil) {
        _infoLab = [[UILabel alloc] init];
//        _infoLab.text = self.textField.text;
        _infoLab.numberOfLines = 3;
//        _infoLab.backgroundColor = [UIColor blueColor];
        _infoLab.textAlignment = NSTextAlignmentLeft;
        _infoLab.font = [UIFont systemFontOfSize:11];
        _infoLab.textColor = [UIColor blackColor];
        NSMutableParagraphStyle  *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        // 行间距设置为5
        [paragraphStyle  setLineSpacing:5];
        [paragraphStyle setLineBreakMode:NSLineBreakByTruncatingTail];
        NSString  *testString = self.textField.text;
        NSMutableAttributedString  *setString = [[NSMutableAttributedString alloc] initWithString:testString];
        [setString  addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [testString length])];
        // 设置Label要显示的text
        [_infoLab  setAttributedText:setString];
        _infoLab.backgroundColor = [UIColor yellowColor];
    }
    return _infoLab;
}

-(UILabel *)seeTotalLab {
    if (_seeTotalLab == nil) {
        _seeTotalLab = [[UILabel alloc] init];
        _seeTotalLab.text = @"查看全部";
        _seeTotalLab.textAlignment = NSTextAlignmentRight;
        _seeTotalLab.font = [UIFont systemFontOfSize:11];
        _seeTotalLab.textColor = [UIColor blueColor];
        _seeTotalLab.userInteractionEnabled = YES;
        UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] init];
        WS(weakSelf);
        [[tap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
            weakSelf.bgGrayView.frame = CGRectMake(weakSelf.bgGrayView.frame.origin.x, weakSelf.bgGrayView.frame.origin.y, weakSelf.bgGrayView.frame.size.width, _maxHeight + 20 + 18 + (self.lineNeed - 1) * 5);
            weakSelf.infoLab.numberOfLines = 0;
            weakSelf.seeTotalLab.hidden = YES;
            weakSelf.seezoomLab.hidden = NO;
        }];
        [_seeTotalLab addGestureRecognizer:tap];
    }
    return _seeTotalLab;
}


-(UILabel *)seezoomLab {
    if (_seezoomLab == nil) {
        _seezoomLab = [[UILabel alloc] init];
        _seezoomLab.text = @"收起";
        _seezoomLab.textAlignment = NSTextAlignmentRight;
        _seezoomLab.font = [UIFont systemFontOfSize:11];
        _seezoomLab.textColor = [UIColor blueColor];
        _seezoomLab.userInteractionEnabled = YES;
        WS(weakSelf);
        UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] init];
        [[tap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
            weakSelf.bgGrayView.frame = CGRectMake(weakSelf.bgGrayView.frame.origin.x, weakSelf.bgGrayView.frame.origin.y, weakSelf.bgGrayView.frame.size.width, _minHeight + 20 + 18 + (3 - 1) * 5);
            weakSelf.infoLab.numberOfLines = 3;
            weakSelf.seeTotalLab.hidden = NO;
            weakSelf.seezoomLab.hidden = YES;
        }];
        [_seezoomLab addGestureRecognizer:tap];
        
    }
    return _seezoomLab;
}


-(UILabel *)lineLab {
    if (_lineLab == nil) {
        _lineLab = [[UILabel alloc] initWithFrame:CGRectMake(0, 64, Screen_Width, 22)];
        _lineLab.textAlignment = NSTextAlignmentLeft;
        _lineLab.font = [UIFont systemFontOfSize:12];
        _lineLab.textColor = [UIColor blackColor];
    }
    return _lineLab;
}



@end

Demo拉取地址

上一篇下一篇

猜你喜欢

热点阅读