You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS聊天机器人OpenAI API动态表格网格样式优化问询

优化iOS中NSAttributedString表格的行列分隔线方案

1. 自定义表格富文本构建逻辑

放弃依赖OpenAI返回的纯文本分隔线,在visitTable(_ table: Table)方法中手动构建带专业边框样式的表格富文本,完全控制分隔线的样式:

mutating internal func visitTable(_ table: Table) -> NSAttributedString {
    let mutableAttributedString = NSMutableAttributedString()
    
    // 计算列宽(基于屏幕宽度减去边距后均分)
    let totalAvailableWidth = UIScreen.main.bounds.width - 40
    let columnCount = table.header?.cells.count ?? table.rows.first?.cells.count ?? 0
    guard columnCount > 0 else { return mutableAttributedString }
    let columnWidth = totalAvailableWidth / CGFloat(columnCount)
    
    // 处理表头
    if let header = table.header {
        let headerRow = buildStyledTableRow(cells: header.cells, columnWidth: columnWidth, isHeader: true)
        mutableAttributedString.append(headerRow)
        // 添加加粗的表头底部分隔线
        let headerSeparator = NSAttributedString(string: "\n", attributes: [
            NSAttributedString.Key.strokeColor: UIColor.black,
            NSAttributedString.Key.strokeWidth: 2.0
        ])
        mutableAttributedString.append(headerSeparator)
    }
    
    // 处理表格行
    for row in table.rows {
        let rowString = buildStyledTableRow(cells: row.cells, columnWidth: columnWidth, isHeader: false)
        mutableAttributedString.append(rowString)
        // 添加细灰色的行分隔线
        let rowSeparator = NSAttributedString(string: "\n", attributes: [
            NSAttributedString.Key.strokeColor: UIColor.lightGray,
            NSAttributedString.Key.strokeWidth: 1.0
        ])
        mutableAttributedString.append(rowSeparator)
    }
    
    return mutableAttributedString
}

// 辅助方法:构建带样式的单行富文本
private func buildStyledTableRow(cells: [TableCell], columnWidth: CGFloat, isHeader: Bool) -> NSAttributedString {
    let rowMutableString = NSMutableAttributedString()
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.alignment = .center
    paragraphStyle.lineBreakMode = .byWordWrapping
    
    // 单元格基础样式
    let baseAttributes: [NSAttributedString.Key: Any] = [
        .font: isHeader ? UIFont.boldSystemFont(ofSize: 16) : UIFont.systemFont(ofSize: 14),
        .paragraphStyle: paragraphStyle,
        .foregroundColor: isHeader ? UIColor.darkGray : UIColor.black
    ]
    
    for (index, cell) in cells.enumerated() {
        // 用Markdownosaur解析单元格内的高亮内容
        let cellContent = visitTableCell(cell)
        let styledCellContent = NSMutableAttributedString(attributedString: cellContent)
        styledCellContent.addAttributes(baseAttributes, range: NSRange(location: 0, length: styledCellContent.length))
        
        // 添加左侧边框
        let leftBorder = NSAttributedString(string: "| ", attributes: [
            .strokeColor: UIColor.lightGray,
            .strokeWidth: 1.0
        ])
        rowMutableString.append(leftBorder)
        rowMutableString.append(styledCellContent)
        
        // 添加右侧边框(最后一列单独处理)
        if index == cells.count - 1 {
            let rightBorder = NSAttributedString(string: " |", attributes: [
                .strokeColor: UIColor.lightGray,
                .strokeWidth: 1.0
            ])
            rowMutableString.append(rightBorder)
        }
    }
    
    rowMutableString.append(NSAttributedString(string: "\n"))
    return rowMutableString
}

2. 修改Markdownosaur的表格分隔线解析规则

如果希望保留原有Markdown解析流程,仅替换分隔线样式,可以修改Markdownosaur中处理表格分隔线的逻辑,将纯文本---|---转换为带下划线样式的富文本:

// 在Markdownosaur的表格解析模块中添加此方法
func parseStyledTableSeparator(_ separatorLine: String) -> NSAttributedString {
    let separatorAttributes: [NSAttributedString.Key: Any] = [
        .underlineStyle: NSUnderlineStyle.single.rawValue,
        .underlineColor: UIColor.black,
        .font: UIFont.systemFont(ofSize: 1) // 缩小字体让下划线更贴合专业表格样式
    ]
    // 清理分隔线中的竖线,替换为空格避免干扰
    let cleanSeparator = separatorLine.replacingOccurrences(of: "|", with: " ")
    return NSAttributedString(string: cleanSeparator, attributes: separatorAttributes)
}

3. 基于CoreText的自定义绘制(最高自由度)

若需要极致的样式控制(如圆角边框、渐变线条等),可以在承载富文本的控件子类中重写draw(_ rect: CGRect)方法,直接用CoreText绘制表格边框:

// 自定义UITextView子类
class TableTextView: UITextView {
    override func draw(_ rect: CGRect) {
        super.draw(rect)
        
        guard let tableAttrString = self.attributedText else { return }
        let context = UIGraphicsGetCurrentContext()
        guard let ctx = context else { return }
        
        // 配置边框样式
        ctx.setStrokeColor(UIColor.lightGray.cgColor)
        ctx.setLineWidth(1.0)
        
        // 计算列分隔线位置
        let columnCount = 5 // 根据实际表格列数动态获取
        let totalWidth = self.bounds.width - 40
        let columnWidth = totalWidth / CGFloat(columnCount)
        
        // 绘制列分隔线
        for columnIndex in 1..<columnCount {
            let xPos = 20 + columnWidth * CGFloat(columnIndex)
            ctx.move(to: CGPoint(x: xPos, y: 20))
            ctx.addLine(to: CGPoint(x: xPos, y: self.bounds.height - 20))
            ctx.strokePath()
        }
        
        // 绘制行分隔线(需根据文本布局计算行高和位置)
        // 可通过CoreText的CTFramesetter获取每行的位置信息,此处省略具体实现
    }
}

内容的提问来源于stack exchange,提问作者artit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 02:05:37