iOS 结合YYLabel实现文本的展开和收起

项目需要实现文本过多的时候最多展示五行,其余的折叠。点击可展开,再次点击可收起。

效果如下:

这是在UITableView的Cell里实现的,需要自适应高度。

一开始自定义了一个UIView直接追加到需要添加展开的最后一行的最后位置,覆盖了展示的内容。实现的并不完美。效果如下:

UI提出了改进:展开和收起都需要更在文本末尾。

网上搜索了一下下,找到了适合自己的方法:链接     

下面记录一下,加强记忆。

我这里是借用的xib来实现的布局,所以这段文本的高度单独拿出来了

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *detailHeight;

获取五行文本的高度

self.attDic = [NSString attDicWithFont:[UIFont systemFontOfSize:[NSString iPhoneFont:T_2 iPadFont:T_2 + 4]]
                                 textColor: [UIColor useLight:HexColor(0x616A73) Dark:HexAColor(DarkTitle,.6)]
                               textSpacing:0
                               lineSpacing:5
                        lineHeightMultiple:0
                       firstLineHeadIndent:0
                                 alignment:(NSTextAlignmentJustified)
                                headIndent:0
                                tailIndent:0
                    paragraphSpacingBefore:0
                          paragraphSpacing:0];
    
self.heightOfFiveLines = [NSString getHeightOfAttributedString:@"五\n行\n文\n字\n字" width:200 attibuteDic:self.attDic];
//attDic是自己封装的包含文本属性的字典
//文本显示的处理
- (void)setTextForDetail:(NSString *)introInfos {
    if (![introInfos isEqualToString:@""]) {
        self.label_detail.hidden = NO;
        self.background_detail.hidden = NO;
        self.label_detail.attributedText = [[NSAttributedString alloc]initWithString:introInfos attributes:self.attDic];
        self.heightsOfTexts = [NSString getHeightOfAttributedString:introInfos width:SCREEN_WIDTH-30*2 attibuteDic:self.attDic];//文本高度
        
        if (self.heightsOfTexts <= self.heightOfFiveLines) {//不需要折叠,不需要添加展开
            self.label_detail.userInteractionEnabled = NO;
            self.label_detail.numberOfLines = 0;
            self.detailHeight.constant = self.heightsOfTexts + 12*2;
            self.topMargin.constant = 10;
        }else{
            self.label_detail.userInteractionEnabled = YES;
            self.view_fold.hidden = NO;
            if (self.foldStatus) {//折叠态
                self.label_detail.numberOfLines = 5;
                self.detailHeight.constant = self.heightOfFiveLines + 12*2;
                [self setAdjustableTextWithDesc:introInfos];
            }else{
                self.heightsOfTexts = [NSString getHeightOfAttributedString:[NSString stringWithFormat:@"%@...收起",introInfos] width:SCREEN_WIDTH-30*2 attibuteDic:self.attDic];
                self.label_detail.numberOfLines = 0;
                self.detailHeight.constant = self.heightsOfTexts + 12*2;
                [self setShowTextWithDesc:introInfos];
            }
            self.topMargin.constant = 10;
        }
    }else{
        self.label_detail.hidden = YES;
        self.label_detail.text = @"";
        self.background_detail.hidden = YES;
        self.detailHeight.constant = 0;
        self.topMargin.constant = -20;
    }
}
//追加“...收起”
- (void)setShowTextWithDesc:(NSString *)desc {
    NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@...收起",desc] attributes:self.attDic];
    
    @weakify(self)
    //设置高亮色和点击事件
    [text yy_setTextHighlightRange:[[text string] rangeOfString:@"收起"]
                             color:HexColor(0x29CCCC)
                   backgroundColor:[UIColor clearColor]
                         tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {
        @strongify(self)
        [self action_fold];
    }];
    self.label_detail.attributedText = text;
}
//追加“...展开”
- (void)setAdjustableTextWithDesc:(NSString *)desc {
    NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:desc attributes:self.attDic];
    self.label_detail.attributedText = text;
    
    NSMutableAttributedString *showAll = [[NSMutableAttributedString alloc] initWithString:@"...展开" attributes:self.attDic];
    @weakify(self)
    [showAll yy_setTextHighlightRange:[[showAll string] rangeOfString:@"展开"]
                             color:HexColor(0x29CCCC)
                   backgroundColor:[UIColor clearColor]
                         tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {
        @strongify(self)
        [self action_fold];
    }];

//注释掉的地方是一开始用的添加附件这样的方式写的,其实在这个场景中并不需要,直接追加富文本就可
    //YYLabel *seeMore = [YYLabel new];
    //seeMore.attributedText = showAll;
    //seeMore.backgroundColor = [UIColor useLight:HexColor(0xFAFBFC) Dark:HexColor(DarkBackground)];
    //[seeMore sizeToFit];
    //NSMutableAttributedString *truncationToken = [NSAttributedString yy_attachmentStringWithContent:seeMore contentMode:UIViewContentModeScaleToFill attachmentSize:seeMore.size alignToFont:[UIFont systemFontOfSize:[NSString iPhoneFont:T_2 iPadFont:T_2 + 4]] alignment:YYTextVerticalAlignmentTop];
    //self.label_detail.truncationToken = truncationToken;

    self.label_details.truncationToken = showAll;
}

点击事件是个block,回传给UITableView

- (void)action_fold{
    if (self.block_fold) {
        self.block_fold([NSNumber numberWithBool:self.foldStatus]);
    }
}

UITableView的代理方法:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath的处理

BookSheetDetailListBCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BookSheetDetailListBCell"];
cell.foldStatus = [self.foldStatusArray[indexPath.row] boolValue];
cell.infoDic = self.dataArray[indexPath.row];
cell.block_fold = ^(id  _Nonnull info) {
                    @strongify(self)
                    self.foldStatusArray[indexPath.row] = @(![info boolValue]);
                    [self.tableView reloadRowAtIndexPath:indexPath withRowAnimation:(UITableViewRowAnimationFade)];
                };
return cell;

默认是不展开的状态。

猜你喜欢

转载自blog.csdn.net/jdd92/article/details/126769130