Custom Cells
Create custom cell layouts using Auto Layout for complete visual control.
When to Use Custom Cells
While SwiftDataTables' default cells handle most cases, you may need custom layouts for:
- Complex multi-element cells
- Images or icons alongside text
- Interactive elements (buttons, switches)
Just need custom fonts or colours? Use defaultCellConfiguration instead - it's much simpler.
Step 1: Create Your Cell Class
class ProductCell: UICollectionViewCell {
let nameLabel = UILabel()
let priceLabel = UILabel()
let statusIndicator = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupViews() {
contentView.addSubview(nameLabel)
contentView.addSubview(priceLabel)
contentView.addSubview(statusIndicator)
nameLabel.font = .systemFont(ofSize: 14, weight: .medium)
priceLabel.font = .systemFont(ofSize: 14)
priceLabel.textColor = .secondaryLabel
// Auto Layout constraints...
}
func configure(name: String, price: String, isActive: Bool) {
nameLabel.text = name
priceLabel.text = price
statusIndicator.backgroundColor = isActive ? .systemGreen : .systemRed
}
}Step 2: Create a Custom Cell Provider
let provider = DataTableCustomCellProvider(
register: { collectionView in
collectionView.register(ProductCell.self, forCellWithReuseIdentifier: "product")
},
reuseIdentifierFor: { indexPath in
return "product"
},
configure: { cell, value, indexPath in
guard let productCell = cell as? ProductCell else { return }
let text = value.stringRepresentation
productCell.configure(name: text, price: "$99", isActive: true)
},
sizingCellFor: { reuseIdentifier in
return ProductCell() // Off-screen cell for measurement
}
)Step 3: Configure the Table
var config = DataTableConfiguration()
config.cellSizingMode = .autoLayout(provider: provider)
config.rowHeightMode = .automatic(estimated: 60)
let dataTable = SwiftDataTable(data: items, columns: columns, options: config)Different Cells for Different Columns
let provider = DataTableCustomCellProvider(
register: { collectionView in
collectionView.register(TextCell.self, forCellWithReuseIdentifier: "text")
collectionView.register(ImageCell.self, forCellWithReuseIdentifier: "image")
collectionView.register(ActionCell.self, forCellWithReuseIdentifier: "action")
},
reuseIdentifierFor: { indexPath in
switch indexPath.section { // Column index
case 0: return "image"
case 4: return "action"
default: return "text"
}
},
// ...
)The sizingCellFor closure is called once per reuse identifier. The returned cell is cached and reused for measurements.