iOS界面整理

iOS实现markdown展示

2025-08-12  本文已影响0人  東玖零

背景:最近AI对话比较热门,AI回复的内容有很多markdown格式,需要展示一下。

三方库:CocoaMarkdown

在github上搜索并下载源码到本地,打开工程文件,选择Any iOS Device编译成功后,在左侧文件栏最下面有一个Products目录,展开找到CocoaMarkdown.framework,将此文件复制到自己的工程,这里是真机的,需要使用模拟器的自己选择模拟器编译进行后再合并,这里不叙述。

下面是关键代码,计算高度

    // 导入
    #import <CocoaMarkdown/CocoaMarkdown.h> 
  
    self.aiResWidth = k_screen_width - 55 - 26 - 10;
    DLog(@"self.dadaAiResWidth = %f",self.aiResWidth);
    CGSize maxSize = CGSizeMake(self.aiResWidth, 100000);
    
    // 1.字符串转data
    NSData *data = [self.body dataUsingEncoding:NSUTF8StringEncoding];

    // 2. 渲染成 NSAttributedString
    CMDocument *doc = [[CMDocument alloc] initWithData:data options:CMDocumentOptionsSmart];
    
    // 3. 创建属性对象
    CMTextAttributes *attrs = [[CMTextAttributes alloc] init];
    [attrs addStringAttributes:@{NSFontAttributeName:kFont14} forElementWithKinds:CMElementKindAnyHeader];
    [attrs addStringAttributes:@{NSFontAttributeName:kFont13} forElementWithKinds:CMElementKindParagraph];
    [attrs addStringAttributes:@{NSFontAttributeName:kFont13} forElementWithKinds:CMElementKindText];
    CMAttributedStringRenderer *renderer = [[CMAttributedStringRenderer alloc] initWithDocument:doc
                                                 attributes:attrs];
    NSAttributedString *attrStr = [renderer render];
    [self setAttrStr:attrStr];
    
    // 4. 计算高度,给定最大宽度(例如 tableView 的 contentWidth)
    CGRect boundingRect = [attrStr boundingRectWithSize:maxSize
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                              context:nil];
    self.aiResHeight = ceil(boundingRect.size.height);

下面是关键代码,使用UITextView进行渲染

- (UITextView *)body {
    if (!_body) {
        CGRect rect = CGRectMake(16, 10, 197, 80);
        _body = [[UITextView alloc] initWithFrame:rect];
        _body.font = kFont13;
        _body.textColor = kBlackColorD;
        _body.editable = NO;
        _body.scrollEnabled = NO;  // 如果外层有 UIScrollView/UITableView 就关掉
        _body.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);// 去掉上下默认8pt边距
        _body.textContainer.lineFragmentPadding = 0; // 去掉左右 5 pt 的边距
        [_body setContentCompressionResistancePriority:UILayoutPriorityRequired
                                                  forAxis:UILayoutConstraintAxisVertical];
    }
    return _body;
}
// 赋值显示
self.body.attributedText = att.attrStr;
// 设置位置
self.body.frame = CGRectMake(16, 12, att.aiResWidth, att.aiResHeight);

注:去掉边距比较重要, 不然显示可能会少一行。

上一篇 下一篇

猜你喜欢

热点阅读