---
title: Adding tables to attributed strings in UIKit
framework: uikit
role: article
role_heading: Article
path: uikit/adding-tables-to-attributed-strings
---

# Adding tables to attributed strings in UIKit

Create and configure tables in attributed strings and display them in a text view.

## Overview

Overview NSTextTable and its related classes let you embed tables of rows and columns directly into NSAttributedString objects on all Apple platforms. NSAttributedString stores a string together with per-character formatting attributes — such as fonts, colors, and paragraph styles — and is the primary text type for UIKit text views. You build a table from three objects: NSTextTable represents the table as a whole and defines the column count and layout algorithm. NSTextTableBlock represents a single cell and records the cell’s row, column, and span values. It belongs to a parent table. NSTextBlock is the base class, and it defines the visual properties (background color, border, padding, margin) that both tables and individual cells share. You build a table by creating one NSTextTable, then creating one NSTextTableBlock per cell and assigning each block to a paragraph in the attributed string using textBlocks. The text system reads the textBlocks array of adjacent paragraphs to determine the table’s structure. Create the table and its cells Start by creating the table and configuring its column count. The following code shows how to create a table with three equally sized columns and enable collapsed borders so adjacent cells share a single border line: let table = NSTextTable() table.numberOfColumns = 3 table.collapsesBorders = true Then create a block for each cell, specifying its position and span within the table. The following helper function creates a cell at the specified row and column, sets its width to one-third of the available space, and applies a light gray background, a separator-colored 1-point border, and 4 points of padding on all edges: func makeCell(row: Int, column: Int, in table: NSTextTable) -> NSTextTableBlock {     let cell = NSTextTableBlock(         table: table,         startingRow: row, rowSpan: 1,         startingColumn: column, columnSpan: 1     )     cell.setContentWidth(33, type: .percentage)     cell.backgroundColor = UIColor.secondarySystemBackground     cell.setBorderColor(.separator)     cell.setWidth(1, type: .absolute, for: .border)     cell.setWidth(4, type: .absolute, for: .padding)     return cell } Apply cells to paragraphs Each cell maps to exactly one paragraph in the attributed string. Assign the cell block to that paragraph using NSMutableParagraphStyle.textBlocks. The following code builds a 2×3 table — two rows and three columns — by creating a cell block for each position and appending a styled paragraph for each cell to the attributed string: let string = NSMutableAttributedString()

for row in 0..<2 {     for column in 0..<3 {         let cell = makeCell(row: row, column: column, in: table)

let style = NSMutableParagraphStyle()         style.textBlocks = [cell]

let cellText = NSAttributedString(             string: "Row \(row), Col \(column)\n",             attributes: [.paragraphStyle: style]         )         string.append(cellText)     } } The textBlocks array is ordered from outermost to innermost block. For a table without nested blocks, each cell paragraph has a single-element array. Configure per-edge widths and colors You can set widths and border colors independently for each edge using setWidth(_:type:for:rectEdge:) and setBorderColor(_:rectEdge:). For example, the following code applies a 2-point blue border to the bottom edge of a cell, leaving the other edges unchanged: cell.setWidth(2, type: .absolute, for: .border, rectEdge: .maxYEdge) cell.setBorderColor(.systemBlue, rectEdge: .maxYEdge) Use the CGRectEdge values CGRectEdge.minXEdge (leading), CGRectEdge.maxXEdge (trailing), CGRectEdge.minYEdge (top), and CGRectEdge.maxYEdge (bottom). To support iOS 26 and earlier, use setWidth(_:type:for:) and setBorderColor(_:) to apply a uniform width or color to all edges. Choose a layout algorithm By default, NSTextTable.LayoutAlgorithm.automatic distributes width based on content. Use NSTextTable.LayoutAlgorithm.automatic when you want your column widths to adapt to the content — for example, a label-value table where short labels sit beside values that vary in length. If you want consistent, predictable column widths regardless of content length, use NSTextTable.LayoutAlgorithm.fixed, which distributes width based on the explicit contentWidth values set on the first row of cells. For example, if your app displays a data grid where each column always occupies one-third of the available width, set each first-row cell to 33 percent and switch to fixed layout: table.layoutAlgorithm = .fixed Display the result Assign the attributed string to a UITextView to render the table. The text system reads the paragraph style information embedded in the string to interpret the table structure automatically, so no extra configuration of the view is required: textView.attributedText = string

## See Also

### Formatting and attributes

- [NSParagraphStyle](uikit/nsparagraphstyle.md)
- [NSMutableParagraphStyle](uikit/nsmutableparagraphstyle.md)
- [NSTextTab](uikit/nstexttab.md)
- [NSTextList](uikit/nstextlist.md)
