美文网首页
iOSLabel自适应高度实现

iOSLabel自适应高度实现

作者: 数字d | 来源:发表于2021-09-10 19:00 被阅读0次

    需求:根据服务端返回的字符串数据来展示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拉取地址

    相关文章

      网友评论

          本文标题:iOSLabel自适应高度实现

          本文链接:https://www.haomeiwen.com/subject/vgsnwltx.html