[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fdhg-fE2qspSwG3zQ6WxqyrgmPXNsncNxzPf-dptWIgE":3},{"code":4,"message":5,"data":6},200,"成功",{"id":7,"createdAt":8,"title":9,"content":10,"summary":11,"image":12,"uid":13,"user":14,"categoryId":21,"category":22,"subCategoryId":24,"subCategory":25,"comments":27,"status":17,"reason":12,"notice":12,"visitCount":28,"commentCount":29,"keywords":30},28,"2024-01-29T14:27:48.349Z","使用YYLabel来实现收起和展开，嵌入#话题并允许点击","总结：这里实现的方式使用了numberOfLines属性，配合YYText的富文本增加点击事件，以及Masory布局来实现展开和收起，以及点击话题。\n如果需要控制折叠状态下的文本字数，可以直接截取富文本的某一段就可以了，这里不赘述。\n\n# 一、依赖 YYText\n```podfile\npod 'YYText'\n```\n\n# 二、实例化YYLabel作为文本组件\n注意：要设置一下preferredMaxLayoutWidth，控制文本的宽度\n（以下代码中的颜色和字体可根据自己需要自行设置，这里是使用我们自己封装的字体和颜色）\n```implemention.m\n- (YYLabel *)descLabel {\n    if (!_descLabel) {\n        _descLabel = [[YYLabel alloc] init];\n        _descLabel.font = [DZFontStyle pingFangFontOfSize:14];\n        _descLabel.textColor = UIColorWithHex(@\"#E0E1E6\");\n        _descLabel.textAlignment = NSTextAlignmentLeft;\n        _descLabel.numberOfLines = 2;\n        _descLabel.lineBreakMode = NSLineBreakByTruncatingTail;\n        _descLabel.preferredMaxLayoutWidth = CONTAINER_WIDTH;\n    }\n    return _descLabel;\n}\n```\n\n# 三、获取富文本\n1.第一步就是将整个的普通字符串，添加字体、颜色属性成富文本，再链接append上话题的富文本，形成了一个完整的富文本；\n2.这一步需要设置展开状态下的富文本：\n普通字符串富文本 + #话题#富文本及点击事件 + 省略号...(可选，这里我使用了空格) + “收起”image及点击事件\n3.折叠状态下的富文本，就是完整的富文本；（折叠状态下显示“展开”的操作在下一节）\n4.避免重复计算展开和折叠状态下的富文本，所以使用2个变量接收第一次算出来的富文本\n5.在label所在的代码作用域，实现“收起”的点击事件（下面代码是用block交给外层）\n```implemention.m\n/// 处理图片描述富文本\n- (NSAttributedString *)videoLayerDescAttStrWithDescWidth:(CGFloat)descWidth {\n    // 普通字符串\n    NSString *allStr = DZRealString(self.videoInfoVO.des);\n    // 富文本\n    NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:allStr];\n    NSRange range = NSMakeRange(0, attStr.length);\n    if (range.location != NSNotFound) {\n        [attStr addAttribute:NSFontAttributeName value:Font(14) range:range];\n        [attStr addAttribute:NSForegroundColorAttributeName value:UIColorFromRGB(0xE0E1E6) range:range];\n    }\n    //话题，如果存在，添加点击方法（这里使用block交给外部实现），就append起来\n    NSString *topicStr = nil;\n    NSMutableAttributedString *topicAttStr = nil;\n    if (!IsEmpty(self.topicInfoVO)) {\n        topicStr = [NSString stringWithFormat:@\"#%@#\", DZRealString(self.topicInfoVO.title)];\n        topicAttStr = [[NSMutableAttributedString alloc] initWithString:topicStr attributes:@{NSFontAttributeName:[DZFontStyle pingFangMediumFontOfSize:14], NSForegroundColorAttributeName:UIColorFromRGB(0xFFFFFF)}];\n        @weakify_dzx(self);\n        [topicAttStr yy_setTextHighlightRange:NSMakeRange(0, topicAttStr.length) color:UIColorFromRGB(0xFFFFFF) backgroundColor:[UIColor clearColor] tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {\n            @strongify_dzx(self);\n            if (self.topicClick) {\n                self.topicClick();\n            }\n        }];\n        [attStr appendAttributedString:topicAttStr];\n    }\n    // 这里是2行的宽度，减去\"收起\"图片的宽度，就是展示整个富文本的总宽度\n    CGFloat descTwoLineMaxWidth = descWidth * 2.0 - 35;\n    // 富文本需要展示完全的宽度\n    CGRect fullStrRectInOneLine = [attStr boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) context:nil];\n    \n    if (fullStrRectInOneLine.size.width > descTwoLineMaxWidth) { // 超出2行 折叠起来了\n        if (self.isExpand) {\n            if (self.expandDescAttri) {\n                return self.expandDescAttri;\n            } else {\n                // 这里控制的是，让\"展开\"状态下的富文本最多字数为100，\n                if (attStr.length > 100) {\n                    attStr = [[NSMutableAttributedString alloc] initWithAttributedString:[attStr attributedSubstringFromRange:NSMakeRange(0, 100)]];\n                }\n                // append 空格\n                [attStr appendAttributedString:[[NSAttributedString alloc] initWithString:@\" \" attributes:@{NSForegroundColorAttributeName : [UIColor whiteColor], NSFontAttributeName : Font(14)}]];\n                // append \"收起\"图片的attachment\n                NSAttributedString *imgAttri = [NSAttributedString yy_attachmentStringWithContent:[UIImage imageNamed:@\"immersion_video_desc_collapse\"] contentMode:UIViewContentModeCenter attachmentSize:CGSizeMake(35, 16) alignToFont:[DZFontStyle pingFangFontOfSize:16] alignment:(YYTextVerticalAlignmentCenter)];\n                [attStr appendAttributedString:imgAttri];\n                // 点击\"收起\"的事件\n                @weakify_dzx(self);\n                NSRange attachmentRange = NSMakeRange(attStr.length - 1, 1);\n                [attStr yy_setTextHighlightRange:attachmentRange color:nil backgroundColor:nil tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {\n                    @strongify_dzx(self);\n                    if (self.videoCollapseClick) {\n                        self.videoCollapseClick();\n                    }\n                }];\n                // 拼接成最终的富文本\n                attStr = [[NSMutableAttributedString alloc] initWithAttributedString:[[self class] addParagraphForAttri:attStr]];\n                self.expandDescAttri = attStr;\n                return attStr;\n            }\n        } else {\n            if (self.foldDescAttri) {\n                return self.foldDescAttri;\n            } else {\n                // 完整的富文本\n                attStr = [[NSMutableAttributedString alloc] initWithAttributedString:[[self class] addParagraphForAttri:attStr]];\n                self.foldDescAttri = attStr;\n                return attStr;\n            }\n        }\n    } else { // 未超出2行\n        return attStr;\n    }\n    return attStr;\n}\n// 这里加了富文本的行间距属性\n+ (NSAttributedString *)addParagraphForAttri:(NSAttributedString *)attStr {\n    NSRange attRange = NSMakeRange(0, attStr.length);\n    if (attRange.location != NSNotFound) {\n        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];\n        paragraphStyle.lineSpacing = 5;\n        paragraphStyle.paragraphSpacing = 0;\n        paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;\n        NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithAttributedString:attStr];\n        [attributedStr addAttributes:@{ NSParagraphStyleAttributeName : paragraphStyle} range:attRange];\n        return attributedStr;\n    }\n    return attStr;\n}\n```\n6. 收起事件的实现\n```implemention.m\n// \"收起\"\n    infoVo.videoCollapseClick = ^{\n        weakSelf.infoVo.isExpand = NO;\n        weakSelf.descLabel.numberOfLines = 2;\n        weakSelf.descLabel.attributedText = [weakSelf.infoVo videoLayerDescAttStrWithDescWidth:CONTAINER_WIDTH];\n    };\n```\n\n# 四、折叠状态下的“展开”+ 点击展开事件\n1. 使用YYLabel的truncationToken，来显示“展开”。\n```implemention.m\n// 这里使用变量属性truncationToken，后面会赋值给YYLabel\n- (NSAttributedString *)truncationToken{\n    if (!_truncationToken) {\n        // 展开图片的size\n        CGSize imageSize = CGSizeMake(57, 27);\n        // 容器view，子视图是省略号+展开image\n        UIView *trailingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, imageSize.width, imageSize.height)];\n        // 给容器视图加点击事件，点击后就显示展开状态下的富文本\n        @weakify_dzx(self);\n        [trailingView addTapGestureActionWithBlock:^(UITapGestureRecognizer * _Nonnull tapAction) {\n            @strongify_dzx(self);\n            [self tapExpandAction];\n        }];\n        // 省略号\n        UILabel *dotLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 6, 22, 17)];\n        dotLabel.font = [DZFontStyle pingFangFontOfSize:14];\n        dotLabel.textColor = [UIColor whiteColor];\n        dotLabel.text = @\"...\";\n        // 展开image\n        UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@\"immersion_video_desc_expand\"]];\n        imageView.frame = CGRectMake(22, 6, 35, 16);\n        // 添加进容器\n        [trailingView addSubview:dotLabel];\n        [trailingView addSubview:imageView];\n        \n        _truncationToken = [NSAttributedString yy_attachmentStringWithContent:trailingView contentMode:UIViewContentModeCenter attachmentSize:imageSize alignToFont:[DZFontStyle pingFangFontOfSize:16] alignment:(YYTextVerticalAlignmentCenter)];\n    }\n    return _truncationToken;\n}\n```\n2. 赋值truncationToken\n```implemention.m\nself.descLabel.truncationToken = self.truncationToken;\n```\n3. 展开的实现\n```implemention.m\n/// 点击展开\n- (void)tapExpandAction {\n    self.infoVo.isExpand = YES;\n    self.descLabel.numberOfLines = 0; // 不限行\n    self.descLabel.attributedText = [self.infoVo videoLayerDescAttStrWithDescWidth:CONTAINER_WIDTH];\n}\n```\n\n# 五、给YYLabel赋值\n```implemention.m\n// 描述\n    self.descLabel.attributedText = [infoVo videoLayerDescAttStrWithDescWidth:CONTAINER_WIDTH];\n```","在objective-c中，实现文本的折叠和展开。这里实现的方式使用了numberOfLines属性，配合YYText的富文本增加点击事件，以及Masory布局来实现展开和收起，以及点击话题。如果需要控制折叠状态下的文本字数，可以直接截取富文本的某一段就可以了。","",499668042977349,{"phone":15,"userId":13,"nickName":16,"vipType":17,"avatar":18,"sign":19,"createdAt":20},"13121171998","全栈老韩",1,"https://image.xinwei.ltd/images/IMG_5430.JPG","全栈工程师，擅长iOS App开发、前端（vue、react、nuxt、小程序&Taro）开发、Flutter、React Native、后端（midwayjs、golang、express、koa）开发、docker容器、seo优化等。","2024-01-01T16:14:30.305Z",2,{"id":21,"name":23},"IT技术",3,{"id":24,"name":26,"parentId":21},"iOS",[],1121,0,"ios,label,ios label,iOS文本,iOS文本折叠"]