iOS使用YYLabel 点击展开和收起全文

看图说话比较清晰,点击红色标记的区域,会展开全文。

 

相关知识点

  • YYLabel,truncationToken
  • NSAttributedString,YYText,YYTextHighlight

我们来看一下YYLabel的属性truncationToken,是一个富文本,当Label被截断时,该富文本显示在文末,默认与UILabel显示的一样,是三个点。

/**
 The truncation token string used when text is truncated. Default is nil.
 When the value is nil, the label use "…" as default truncation token.
 */
@property (nullable, nonatomic, copy) NSAttributedString *truncationToken;

我们可以使用以下方式来指定切断文本:

YYLabel *label = [YYLabel new];
lable.text = @"我们可以使用以下方式来指定切断文本";
NSAttributedString *truncationToken = [[NSAttributedString alloc] initWithString:@"… 展开"]];
label.truncationToken = truncationToken;

接着来了解一下实现点击响应事件的YYTextHighlight 和 tapAction

/**
 YYTextHighlight objects are used by the NSAttributedString class cluster
 as the values for touchable highlight attributes (stored in the attributed string
 under the key named YYTextHighlightAttributeName).
 
 When display an attributed string in `YYLabel` or `YYTextView`, the range of 
 highlight text can be toucheds down by users. If a range of text is turned into 
 highlighted state, the `attributes` in `YYTextHighlight` will be used to modify 
 (set or remove) the original attributes in the range for display.
 */
@interface YYTextHighlight : NSObject <NSCoding, NSCopying>

在YYLabel或者YYTextView的富文本中,指定YYTextHighlight的范围,用户就可以在该范围内实现点击效果。

/**
 The tap/long press action callback defined in YYText.
 
 @param containerView The text container view (such as YYLabel/YYTextView).
 @param text          The whole text.
 @param range         The text range in `text` (if no range, the range.location is NSNotFound).
 @param rect          The text frame in `containerView` (if no data, the rect is CGRectNull).
 */
typedef void(^YYTextAction)(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect);

/**
 Tap action when user tap the highlight, default is nil.
 If the value is nil, YYTextView or YYLabel will ask it's delegate to handle the tap action.
 */
@property (nullable, nonatomic, copy) YYTextAction tapAction;

tapAction是一个block回调,在用户点击highlight时会触发。如果没有指定tapAction, 点击会使用delegate的方式触发。

//添加点击事件
    YYTextHighlight *hi = [YYTextHighlight new];
    [text yy_setTextHighlight:hi range:[text.string rangeOfString:moreString]];
    
    hi.tapAction = ^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect) {
      //这里是自己的代码
    };

最终的代码

- (YYLabel *)tokenLabel {
    if (!_tokenLabel) {
        _tokenLabel = [YYLabel new];
        _tokenLabel.frame = CGRectMake(20, 100, [UIScreen mainScreen].bounds.size.width - 40, 30);
        _tokenLabel.numberOfLines = 0;
        _tokenLabel.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.75];
        [self addSeeMoreButtonInLabel:_tokenLabel];
        
    }
    
    return _tokenLabel;
}

- (void)addSeeMoreButtonInLabel:(YYLabel *)label {
    UIFont *font16 = [UIFont systemFontOfSize:16];
    label.attributedText = [[NSAttributedString alloc] initWithString:@"我们可以使用以下方式来指定切断文本; 收起 我们可以使用以下方式来指定切断文本" attributes:@{NSFontAttributeName : font16}];

    NSString *moreString = @" 展开";
    NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"... %@", moreString]];
    NSRange expandRange = [text.string rangeOfString:moreString];
    
    [text addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:expandRange];
    [text addAttribute:NSForegroundColorAttributeName value:[UIColor darkTextColor] range:NSMakeRange(0, expandRange.location)];
    
    //添加点击事件
    YYTextHighlight *hi = [YYTextHighlight new];
    [text yy_setTextHighlight:hi range:[text.string rangeOfString:moreString]];
    
    __weak typeof(self) weakSelf = self;
    hi.tapAction = ^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect) {
        //点击展开
        [weakSelf setFrame:YES];
    };
    
    text.yy_font = font16;
    
    YYLabel *seeMore = [YYLabel new];
    seeMore.attributedText = text;
    [seeMore sizeToFit];
    
    NSAttributedString *truncationToken = [NSAttributedString yy_attachmentStringWithContent:seeMore contentMode:UIViewContentModeCenter attachmentSize:seeMore.frame.size alignToFont:text.yy_font alignment:YYTextVerticalAlignmentTop];
    
    label.truncationToken = truncationToken;
}

- (NSAttributedString *)appendAttriStringWithFont:(UIFont *)font {
    if (!font) {
        font = [UIFont systemFontOfSize:16];
    }
    if ([_tokenLabel.attributedText.string containsString:@"收起"]) {
        return [[NSAttributedString alloc] initWithString:@""];
    }

    
    NSString *appendText = @" 收起 ";
    NSMutableAttributedString *append = [[NSMutableAttributedString alloc] initWithString:appendText attributes:@{NSFontAttributeName : font, NSForegroundColorAttributeName : [UIColor blueColor]}];
    
    YYTextHighlight *hi = [YYTextHighlight new];
    [append yy_setTextHighlight:hi range:[append.string rangeOfString:appendText]];
    
    __weak typeof(self) weakSelf = self;
    hi.tapAction = ^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect) {
        //点击收起
        [weakSelf setFrame:NO];
    };
    
    return append;
}

- (void)expandString {
    NSMutableAttributedString *attri = [_tokenLabel.attributedText mutableCopy];
    [attri appendAttributedString:[self appendAttriStringWithFont:attri.yy_font]];
    _tokenLabel.attributedText = attri;
}

- (void)packUpString {
    NSString *appendText = @" 收起 ";
    NSMutableAttributedString *attri = [_tokenLabel.attributedText mutableCopy];
    NSRange range = [attri.string rangeOfString:appendText options:NSBackwardsSearch];

    if (range.location != NSNotFound) {
        [attri deleteCharactersInRange:range];
    }

    _tokenLabel.attributedText = attri;
}


- (void)setFrame:(BOOL)isExpand {
    if (isExpand) {
        [self expandString];
        self.tokenLabel.frame = CGRectMake(20, 100, [UIScreen mainScreen].bounds.size.width - 40, 200);
    }
    else {
        [self packUpString];
        self.tokenLabel.frame = CGRectMake(20, 100, [UIScreen mainScreen].bounds.size.width - 40, 30);
    }
}

如果需要用UIImage或者UIView等用作truncationToken,可以用以下方法转换成富文本。

使用这个方法可以把UIImage/UIView/CALayer转换成富文本的方式。
+ (NSMutableAttributedString *)yy_attachmentStringWithContent: contentMode:  attachmentSize: alignToFont: alignment:

如果没有把text放到YYLabel里面,而是直接赋值给truncationToken是不会有点击事件的。如下:

//添加点击事件
    YYTextHighlight *hi = [YYTextHighlight new];
    [text yy_setTextHighlight:hi range:[text.string rangeOfString:moreString]];
    
    hi.tapAction = ^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect) {
      //这里是自己的代码
    };
  
    label.truncationToken = text;

 

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS 中,可以使用 YYLabel 来显示富文本,包括 HTML 格式的富文本。YYLabel 是由 YYKit 提供的一个组件,它支持更多的文本属性设置,包括字体、颜色、行间距、字间距等等。 要在 YYLabel 中加载 HTML 富文本,可以使用 NSAttributedString 的 initWithData:options:documentAttributes:error: 方法来实现。具体步骤如下: 1. 将 HTML 字符串转换为 NSData 对象,可以使用 NSString 的 dataUsingEncoding: 方法来实现。 2. 使用 NSAttributedString 的 initWithData:options:documentAttributes:error: 方法,将 NSData 对象转换为 NSAttributedString 对象。 3. 将 NSAttributedString 对象赋值给 YYLabel 的 attributedText 属性,即可在 YYLabel 中显示 HTML 富文本。 下面是一个示例代码: ``` NSString *htmlString = @"<p>This is a <strong>bold</strong> text.</p>"; NSData *htmlData = [htmlString dataUsingEncoding:NSUTF8StringEncoding]; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithData:htmlData options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType} documentAttributes:nil error:nil]; YYLabel *label = [[YYLabel alloc] initWithFrame:CGRectMake(0, 0, 200, 50)]; label.attributedText = attributedString; [self.view addSubview:label]; ``` 上面的代码中,我们首先将 HTML 字符串转换为 NSData 对象,然后使用 NSAttributedString 的 initWithData:options:documentAttributes:error: 方法将其转换为 NSAttributedString 对象。最后,我们将 NSAttributedString 对象赋值给 YYLabel 的 attributedText 属性,即可在 YYLabel 中显示 HTML 富文本。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值