Type-Safe Columns
Define columns using Swift's type system for compile-time safety and cleaner code.
Benefits
The typed API uses DataTableColumn to define how your model properties map to table columns. This approach provides:
- Compile-time safety - Catch typos and type mismatches at build time
- Clean syntax - Use key paths instead of manual array conversion
- Automatic diffing - Enable smooth animated updates via
Identifiable
Basic Key Path Columns
struct Person: Identifiable {
let id: Int
let name: String
let age: Int
let city: String
}
let columns: [DataTableColumn<Person>] = [
.init("Name", \.name),
.init("Age", \.age),
.init("City", \.city)
]Custom Value Extraction
For computed or formatted values, provide a closure:
let columns: [DataTableColumn<Person>] = [
.init("Name", \.name),
.init("Age") { $0.age }, // Returns Int directly
.init("Location") { "\($0.city), \($0.country)" } // Returns String directly
]Formatting Numbers
let columns: [DataTableColumn<Product>] = [
.init("Product", \.name),
.init("Price") { "$\(String(format: "%.2f", $0.price))" },
.init("Discount") { "\(Int($0.discount * 100))%" },
.init("Final") {
let final = $0.price * (1 - $0.discount)
return "$\(String(format: "%.2f", final))"
}
]DataTableValueType
Under the hood, each cell value is a DataTableValueType. The type affects sorting behavior:
public enum DataTableValueType {
case string(String)
case int(Int)
case float(Float)
case double(Double)
}.stringvalues sort alphabetically- Numeric types sort numerically
Explicit Type Control
For computed values where you need specific sorting behavior:
// Computed numeric with numeric sorting: 2 < 9 < 10
.init("Total Score") { .int($0.points + $0.bonus) }
// Formatted string with alphabetical sorting: "10" < "2" < "9"
.init("ID") { String($0.id) }For simple properties, use keypaths instead - they preserve the correct type automatically.
Best Practices
1. Define Columns Once
class EmployeeListVC: UIViewController {
let columns: [DataTableColumn<Employee>] = [
.init("Name", \.name),
.init("Role", \.role)
]
func updateData(_ employees: [Employee]) {
dataTable.setData(employees, animatingDifferences: true)
}
}2. Format for Readability
// Good - formatted strings
.init("Revenue") { "$\($0.revenue.formatted())" }
.init("Growth") { "\(String(format: "%.1f", $0.growth))%" }
// Avoid - raw numbers
.init("Revenue", \.revenue) // Shows "1234567.89"