关于iOS文本展开与收起,使用TextView 的简单实现方法

  • 1、如下示例,设置行距为5的利用富文本使用UITextView进行操作
    这里没有优化,需要优化的自行处理
/// 默认收起的配置
- (void)configDidDownClose{
    NSString * contentsub = @"比特币(Bitcoin)的概念最初由中本聪在2008年11月1日提出, [50]并于2009年1月3日正式诞生 [1]  。根据中本聪的思路设计发布的开源软件以及建构其上的P2P网络。比特币是一种P2P形式的数字货币 [52]  。比特币的交易记录公开透明 [50]  。点对点的传输意味着一个去中心化的支付系统点对点的传输意味";
    self.noteTV.text = [NSString stringWithFormat:@"%@%@",contentsub,@"收起".ntes_localized] ;
    NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
    paraStyle.lineBreakMode =  NSLineBreakByCharWrapping;
    paraStyle.alignment = NSTextAlignmentLeft;
    paraStyle.lineSpacing = 5;
    paraStyle.hyphenationFactor = 0.0;
    paraStyle.firstLineHeadIndent = 0.0;
    paraStyle.paragraphSpacingBefore = 0.0;
    paraStyle.headIndent = 0;
    paraStyle.tailIndent = 0;
    NSDictionary *attributes = @{NSFontAttributeName:FONT(14), NSParagraphStyleAttributeName:paraStyle
    };
    NSMutableAttributedString * attributedText = [[NSMutableAttributedString alloc]init];
    
    NSDictionary *attDict1 = @{NSForegroundColorAttributeName:kColor_ox(0x333333)};
    
    NSAttributedString *attStr1 = [[NSAttributedString alloc] initWithString:[self.noteTV.text substringWithRange:NSMakeRange(0,self.noteTV.text.length - @"收起".ntes_localized.length )] attributes:attDict1];
    
    NSDictionary *attDict2 = @{NSForegroundColorAttributeName:kZhuTiColor};
    NSAttributedString *attStr2 = [[NSAttributedString alloc] initWithString:[self.noteTV.text substringWithRange:NSMakeRange(self.noteTV.text.length - @"收起".ntes_localized.length , @"收起".ntes_localized.length)] attributes:attDict2];
    
    
    [attributedText appendAttributedString:attStr1];
    [attributedText appendAttributedString:attStr2];
    [attributedText addAttributes:attributes range:NSMakeRange(0, self.noteTV.text.length)];
    /// 给富文本后面增加可操作的点击链接通过代理来实现
    NSString *valueString = [[NSString stringWithFormat:@"didDownClose://%@", @"收起".ntes_localized] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
    
    [attributedText addAttribute:NSLinkAttributeName value:valueString range:NSMakeRange(self.noteTV.text.length - @"收起".ntes_localized.length , @"收起".ntes_localized.length)];
    
    _noteTV.attributedText = attributedText;
    
    CGFloat height = [self.noteTV.text getSpaceLabelWithFont:FONT(14) withWidth:SCREEN_WIDTH - 30];
    self.titleContentView = UIView.new;
    [self.titleContentView addSubview:self.noteTV];
    self.titleContentView.frame = CGRectMake(0, 0, SCREEN_WIDTH, height + 15);
    self.noteTV.frame = CGRectMake(15, 15, SCREEN_WIDTH - 30, height);
    [self.tableView setTableHeaderView:self.titleContentView];
}
/// 默认打开的配置
- (void)configDidOpenClose{
    NSString * contentsub = @"比特币(Bitcoin)的概念最初由中本聪在2008年11月1日提出, [50]并于2009年1月3日正式诞生 [1]  。根据中本聪的思路设计发布的开源软件以及建构其上的P2P网络。比特币是一种P2P形式的数字货币 [52]  。比特币的交易记录公开透明 [50]  。点对点的传输意味着一个去中心化的支付系统点对点的传输意味";
    
    
    NSString *tempStr = [self stringByTruncatingString:contentsub suffixStr:@"...全部展开" font:FONT(14) width:SCREEN_WIDTH - 30 num:3];
    self.noteTV.text = tempStr;
    NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
    paraStyle.lineBreakMode =  NSLineBreakByCharWrapping;
    paraStyle.alignment = NSTextAlignmentLeft;
    paraStyle.lineSpacing = 5;
    paraStyle.hyphenationFactor = 0.0;
    paraStyle.firstLineHeadIndent = 0.0;
    paraStyle.paragraphSpacingBefore = 0.0;
    paraStyle.headIndent = 0;
    paraStyle.tailIndent = 0;
    NSDictionary *attributes = @{NSFontAttributeName:FONT(14), NSParagraphStyleAttributeName:paraStyle
    };
    NSMutableAttributedString * attributedText = [[NSMutableAttributedString alloc]init];
    
    NSDictionary *attDict1 = @{NSForegroundColorAttributeName:kColor_ox(0x333333)};
    
    NSAttributedString *attStr1 = [[NSAttributedString alloc] initWithString:[tempStr substringWithRange:NSMakeRange(0,tempStr.length - @"全部展开".ntes_localized.length )] attributes:attDict1];
    
    NSDictionary *attDict2 = @{NSForegroundColorAttributeName:kZhuTiColor};
    NSAttributedString *attStr2 = [[NSAttributedString alloc] initWithString:[tempStr substringWithRange:NSMakeRange(tempStr.length - @"全部展开".ntes_localized.length , @"全部展开".ntes_localized.length)] attributes:attDict2];
    
    
    [attributedText appendAttributedString:attStr1];
    [attributedText appendAttributedString:attStr2];
    [attributedText addAttributes:attributes range:NSMakeRange(0, tempStr.length)];
    /// 给富文本后面增加可操作的点击链接通过代理来实现
    NSString *valueString = [[NSString stringWithFormat:@"didOpenClose://%@", @"全部展开".ntes_localized] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
    
    [attributedText addAttribute:NSLinkAttributeName value:valueString range:NSMakeRange(tempStr.length - @"全部展开".ntes_localized.length , @"全部展开".ntes_localized.length)];
    
    _noteTV.attributedText = attributedText;
    
    CGFloat height = [tempStr getSpaceLabelWithFont:FONT(14) withWidth:SCREEN_WIDTH - 30];
    self.titleContentView = UIView.new;
    [self.titleContentView addSubview:self.noteTV];
    self.titleContentView.frame = CGRectMake(0, 0, SCREEN_WIDTH, height + 15);
    self.noteTV.frame = CGRectMake(15, 15, SCREEN_WIDTH - 30, height);
    [self.tableView setTableHeaderView:self.titleContentView];
    
}
  • 2、核心代码
/// 将文本按长度度截取并加上指定后缀
/// @param str 文本
/// @param suffixStr 指定后缀
/// @param font 文本字体
/// @param textWidth 文本长度
/// @param num 多少行
- (NSString*)stringByTruncatingString:(NSString *)str suffixStr:(NSString *)suffixStr font:(UIFont *)font width:(CGFloat)textWidth num:(NSInteger)num {
    if (!str) return nil;
    CGFloat width = 0;
    int k = 0;
    CGFloat suffixWidth = [suffixStr sizeWithAttributes:@{NSFontAttributeName:font}].width;
    if (str  && [str isKindOfClass:[NSString class]]) {
        for (int i=0; i< [str length];i++){

            NSString *tempStr = [str substringToIndex:i + 1];
           
            CGSize size = [tempStr sizeWithAttributes:@{NSFontAttributeName:font}];
            if ((size.width - width) > textWidth) {
                tempStr = [str substringToIndex:i];
                if (k == num - 1) {
                    str = tempStr;
                     for (int i=(int)[str length] - (int)[suffixStr length]; i< [str length];i = i - (int)[suffixStr length]){
                         tempStr = [str substringToIndex:i];
                         CGSize size = [tempStr sizeWithAttributes:@{NSFontAttributeName:font}];
                         if(size.width - width + suffixWidth  < textWidth){
                             tempStr = [NSString stringWithFormat:@"%@%@", tempStr,suffixStr];
                             str = tempStr;
                             break;
                         }
                     }

                    break;
                }
                width = size.width ;

                k ++;
            }
        }
    }
    return str;
}
  • 3、通过UITextView的代理方法来实现
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
    if ([[URL scheme] isEqualToString:@"didOpenClose"]) {
        [self configDidOpenClose];
        return NO;
    }
    if ([[URL scheme] isEqualToString:@"didDownClose"]) {
        [self configDidDownClose];
        return NO;
    }
    return YES;
}
  • 4、附上计算文本高度
- (CGFloat)getSpaceLabelWithFont:(UIFont*)font withWidth:(CGFloat)width {
    NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
    paraStyle.lineBreakMode = NSLineBreakByCharWrapping;
    paraStyle.alignment = NSTextAlignmentLeft;
    paraStyle.lineSpacing = 5;
    paraStyle.hyphenationFactor = 0.0;
    paraStyle.firstLineHeadIndent = 0.0;
    paraStyle.paragraphSpacingBefore = 0.0;
    paraStyle.headIndent = 0;
    paraStyle.tailIndent = 0;
    NSDictionary *dic = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:paraStyle, NSKernAttributeName:@1.5f
                          };
    
    CGSize size = [self boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:dic context:nil].size;
    
    return size.height;
}

你可能感兴趣的:(关于iOS文本展开与收起,使用TextView 的简单实现方法)