Row Heights
Self-sizing rows that adapt to your content automatically.
By default, all rows have the same fixed height. But when your content varies — long descriptions, multi-line text, or custom cells with different layouts — you need rows that size themselves to fit.
Choosing a Height Mode
SwiftDataTables offers two height modes. Choose based on your content:
| Mode | Best For | Performance |
|---|---|---|
.fixed(CGFloat) | Uniform content, single-line text | Fastest — no measurement needed |
.automatic(estimated:) | Variable content, text wrapping, custom cells | Measures each row via Auto Layout |
Fixed Height
The simplest option. Every row gets the same height, no questions asked.
var config = DataTableConfiguration()
config.rowHeightMode = .fixed(44) // All rows are exactly 44 points tallWhen to use: Your data fits in one line per cell, all cells have similar content, and you want maximum scroll performance.
If content is taller than the fixed height, it gets clipped. There's no truncation indicator — the cell just cuts off.
Automatic Height
Rows measure themselves based on their content. A row with three lines of text will be taller than a row with one line.
var config = DataTableConfiguration()
config.rowHeightMode = .automatic(estimated: 60)The estimated parameter
Before a row scrolls into view, SwiftDataTables doesn't know how tall it is. The estimated value is used as a placeholder until the row is actually measured.
- Too low — Scroll bar jumps as rows turn out taller than expected
- Too high — Wasted space, scroll bar still jumps
- Just right — Smooth scrolling, stable scroll bar
Set estimated to your average row height. If most rows are around 50-60 points, use estimated: 55.
How measurement works
- Initial layout — All rows use the estimated height. This lets the table calculate scroll bounds immediately.
- Lazy measurement — As a row scrolls into view, it's measured using Auto Layout (
systemLayoutSizeFitting). - Height caching — Once measured, the height is cached. Scrolling back to that row reuses the cached value.
- Scroll anchoring — When a row's measured height differs from the estimate, the scroll position adjusts to prevent jumping.
Combining with Text Wrapping
Automatic heights are essential when using text wrapping. Without them, wrapped text gets clipped.
var config = DataTableConfiguration()
// Enable text wrapping
config.textLayout = .wrap
// Let rows grow to fit wrapped text
config.rowHeightMode = .automatic(estimated: 60)
// Cap column width to force wrapping
config.maxColumnWidth = 250Without maxColumnWidth, columns might be wide enough that text never wraps. The cap forces text onto multiple lines, which automatic height then accommodates.
Per-Row Height Overrides
Need specific rows to have custom heights? Use the delegate method:
func dataTable(_ dataTable: SwiftDataTable, heightForRowAt index: Int) -> CGFloat? {
// Make header row taller
if index == 0 {
return 80
}
// Use default height for all other rows
return nil
}Returning nil tells the table to use the configured rowHeightMode. Returning a value overrides it for that specific row.
Live Height Updates
When cell content changes while the user is interacting (typing in a text field, expanding a section), you need to update the row height without disrupting the interaction.
// In your custom cell's text view delegate
func textViewDidChange(_ textView: UITextView) {
// Update your data model
notes[rowIndex].content = textView.text
// Tell the table to remeasure this row
// The cell stays on screen, keyboard stays up, no flicker
dataTable.remeasureRow(rowIndex)
}remeasureRow(_:) only works with .automatic height mode. With .fixed, the height can't change.
Performance with Large Datasets
With 100,000+ rows, measuring each row on-demand can cause micro-stutters during fast scrolling. The prefetchWindow parameter measures rows slightly ahead of the visible area:
config.rowHeightMode = .automatic(estimated: 44, prefetchWindow: 10)This measures 10 rows above and below the visible area in advance. When you scroll, those rows are already measured, eliminating the stutter.
| prefetchWindow | Effect |
|---|---|
| 0 (default) | Only measure rows as they become visible |
| 5-10 | Good balance for most apps |
| 20+ | Very fast scrolling, but uses more memory for cached heights |