如何在NSTextView的NSTextTable中添加嵌套表格?
问题:NSTextTableBlock嵌套表格实现失败
我基于NSTextTableBlock创建了表格,尝试添加嵌套表格但未成功。此前用HTML尝试相同操作时,CSS表格样式仅对首个属性生效。
初始实现代码
@IBOutlet var textView: NSTextView! override func viewDidLoad() { super.viewDidLoad() let table = getTableString() textView.textStorage?.setAttributedString(table) } func getTableString() -> NSMutableAttributedString { var table = NSTextTable() table.numberOfColumns = 4 var mas = NSMutableAttributedString() // Header mas.append(createTableBlock(string: "Header. 1", textTable: table, row: 0, column: 0, width: 25, isHeader: true)) mas.append(createTableBlock(string: "Header. 2", textTable: table, row: 0, column: 1, width: 25, isHeader: true)) mas.append(createTableBlock(string: "Header. 3", textTable: table, row: 0, column: 2, width: 25, isHeader: true)) mas.append(createTableBlock(string: "Header. 4", textTable: table, row: 0, column: 3, width: 25, isHeader: true)) // Row 1 mas.append(createTableBlock(string: "Nr. 1", textTable: table, row: 1, column: 0, width: 25)) mas.append(createTableBlock(string: "Nr. 2", textTable: table, row: 1, column: 1, width: 25)) mas.append(createTableBlock(string: "-mark-", textTable: table, row: 1, column: 2, width: 50)) // Create the nested table var nestedTable = NSTextTable() nestedTable.numberOfColumns = 2 var nestedMAS = NSMutableAttributedString() nestedMAS.append(createTableBlock(string: "Nested 1", textTable: nestedTable, row: 0, column: 0, width: 24, isNested: true)) nestedMAS.append(createTableBlock(string: "Nested 2", textTable: nestedTable, row: 0, column: 1, width: 24, isNested: true)) let needleRange = mas.string.range(of: "-mark-")! let insertionRange = NSRange(needleRange, in: mas.string) mas.replaceCharacters(in: insertionRange, with: nestedMAS) return mas } func createTableBlock(string: String, textTable: NSTextTable, row: Int, column: Int, width: CGFloat, isHeader: Bool = false, isNested: Bool = false) -> NSMutableAttributedString { var offset = 1 if isHeader || isNested { offset = 1 } else if column >= 2 { offset = 2 } let block = NSTextTableBlock(table: textTable, startingRow: row, rowSpan: 1, startingColumn: column, columnSpan: offset) block.backgroundColor = isHeader ? .lightGray : .white block.setBorderColor(isNested ? .red : .green) block.setWidth(1.0, type: NSTextBlock.ValueType.absoluteValueType, for: NSTextBlock.Layer.border) block.setContentWidth(width, type: .percentageValueType) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = isNested ? .center : .left paragraphStyle.textBlocks = [block] var mas = NSMutableAttributedString(string: string + "\n") mas.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, mas.length)) return mas }
效果对比
- 预期效果:

- 实际运行结果:

更新后的问题
已成功在单元格中插入字符串,但无法将其设置为双列单元格形式,更新后的代码如下:
@IBOutlet var textView: NSTextView! override func viewDidLoad() { super.viewDidLoad() let table = getTableString()! textView.textStorage?.setAttributedString(table) } func getTableString() -> NSMutableAttributedString? { let table = NSTextTable() table.numberOfColumns = 4 let mas: NSMutableAttributedString = NSMutableAttributedString() // Header mas.append(addCell(string: "Header. 1\n", textTable: table, row: 0, column: 0, width: 25, isHeader: true)) mas.append(addCell(string: "Header. 2\n", textTable: table, row: 0, column: 1, width: 25, isHeader: true)) mas.append(addCell(string: "Header. 3\n", textTable: table, row: 0, column: 2, width: 25, isHeader: true)) mas.append(addCell(string: "Header. 4\n", textTable: table, row: 0, column: 3, width: 25, isHeader: true)) // Row 1 mas.append(addCell(string: "Nr. 1\n", textTable: table, row: 1, column: 0, width: 25)) mas.append(addCell(string: "Nr. 2\n", textTable: table, row: 1, column: 1, width: 25)) // Composed nested table mas.append(addNestedCell(textTable: table, row: 1, column: 2, width: 50)) return mas } // Regular cell func addCell(string:String, textTable: NSTextTable, row:Int, column:Int, columnSpan:Int=1, width:CGFloat, isHeader:Bool=false, isNested:Bool=false) -> NSMutableAttributedString { let block = createTextTableBlock(table: textTable, row: row, column: column, columnSpan: columnSpan, width: width, isHeader: isHeader, isNested: isNested) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = isNested ? .center : .left paragraphStyle.textBlocks = [block] let mas = NSMutableAttributedString(string: string) mas.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, mas.length)) return mas } // Nested cell func addNestedCell(textTable: NSTextTable, row: Int, column: Int, width: CGFloat) -> NSMutableAttributedString { let parentBlock = createTextTableBlock(table: textTable, row: row, column: column, columnSpan: 2, width: width) // Create the nested table let nestedTable = NSTextTable() nestedTable.numberOfColumns = 2 let nestedMAS = NSMutableAttributedString() // Nested cell 1 nestedMAS.append(addCell(string: "Nested 1\n", textTable: nestedTable, row: 0, column: 0, width: 25, isNested: true)) // Nested cell 2 nestedMAS.append(addCell(string: "Nested 2\n", textTable: nestedTable, row: 0, column: 1, width: 25, isNested: true)) let paraNestStyle = getParagraphStyle(nestedMAS) let textNestBlocks = paraNestStyle!.textBlocks let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = .center paragraphStyle.textBlocks = [parentBlock] paragraphStyle.textBlocks.append(contentsOf: textNestBlocks) nestedMAS.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, nestedMAS.length)) return nestedMAS } // TableBlock builder func createTextTableBlock(table textTable:NSTextTable, row:Int, column:Int, columnSpan:Int=1, width:CGFloat, isHeader:Bool=false, isNested:Bool=false) -> NSTextTableBlock { let block = NSTextTableBlock(table: textTable, startingRow: row, rowSpan: 1, startingColumn: column, columnSpan: columnSpan) block.backgroundColor = isHeader ? .lightGray : .white block.setBorderColor(isNested ? .red : .green) block.setWidth(1.0, type: NSTextBlock.ValueType.absoluteValueType, for: NSTextBlock.Layer.border) block.setContentWidth(width, type: .percentageValueType) return block } // Get paragraph style from NSMutableAttributedString func getParagraphStyle(_ attributedString:NSMutableAttributedString, at index:Int=0) -> NSMutableParagraphStyle? { let range = NSMakeRange(0, attributedString.length) guard let paraStyle = attributedString.attribute(NSAttributedString.Key.paragraphStyle, at:index, longestEffectiveRange:nil, in:range) as? NSMutableParagraphStyle else { return nil } return paraStyle }
当前显示效果

恳请各位提供实现嵌套表格的可行思路或解决方案。
内容的提问来源于stack exchange,提问作者Reinchold
相关产品推荐
相关产品推荐

