top of page
Search
Writer's pictureQuinne Farenwald

Building a Simple UITableView

Updated: Dec 5, 2023

In the realm of iOS development, understanding how to create a UITableView is a fundamental skill. In this tutorial, I'll guide you through the process of setting up a basic UITableView entirely through code, omitting the use of storyboards. We'll also explore the concept of using a ViewModel to manage data efficiently. By the end of this tutorial, you'll be equipped with the knowledge to construct dynamic and organized lists in your iOS applications.


Step 1: Designing the UI Programmatically

Begin by designing your user interface programmatically in the view controller. We'll replace the storyboard-based setup with code. To remove storyboards completely from your project, follow these steps. Here, we're creating a UITableView property and configuring it within the viewDidLoad method.

import UIKit 

class YourViewController: UIViewController { 
   var tableView: UITableView = {
      let tableView = UITableView() 
      tableView.translatesAutoresizingMaskIntoConstraints = false
      return tableView 
   }() 
   
   var viewModel: YourViewModel 
   
   init(viewModel: YourViewModel) {         
      self.viewModel = viewModel         
      super.init(nibName: nil, bundle: nil)     
   }      
   
   // Required initializer for UIViewController
   required init?(coder: NSCoder) {
      fatalError("init(coder:) has not been implemented")     
   }
   
   override func viewDidLoad() {
      super.viewDidLoad() 
      view.backgroundColor = .white 
      
      setupTableView() 
   } 
   
   private func setupTableView() { 
      view.addSubview(tableView) 
      
      NSLayoutConstraint.activate([ 
         tableView.topAnchor.constraint(equalTo: view.topAnchor), 
         tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), 
         tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), 
         tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) 
      } 
  }

Step 2: Create a ViewModel

Just as before, create a ViewModel to handle your data. For simplicity, we've included a sample ViewModel (YourViewModel) that populates an array with sample content.

import Foundation 

class YourViewModel { 
   var data: [String] = [] 
   
   init() { 
      data = ["Item 1", "Item 2", "Item 3", "Item 4"] 
   } 
}

Step 3: Implement UITableViewDataSource and UITableViewDelegate

Adopt the UITableViewDataSource and UITableViewDelegate protocols within your view controller. These protocols dictate how the UITableView should be populated and how it should respond to user interactions.

 class YourViewController: UIViewController { 
 
    private func setupTableView() { 
      view.addSubview(tableView) 
      
      NSLayoutConstraint.activate([ 
         tableView.topAnchor.constraint(equalTo: view.topAnchor), 
         tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), 
         tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), 
         tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) 
         
         // Set delegate and dataSource to this ViewController 
         tableView.delegate = self 
         tableView.dataSource = self 
      } 
   } 
 } 

extension YourViewController: UITableViewDataSource { 
   func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
      return viewModel.data.count 
   }
   
   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
      let cell = UITableViewCell(style: .default, reuseIdentifier: "YourCellIdentifier") 
      cell.textLabel?.text = viewModel.data[indexPath.row] 
      return cell 
   } 
} 

extension YourViewController: UITableViewDelegate { 
   // Implement UITableViewDelegate methods as needed 
}

Step 4: Run Your App

Build and run your app. You should now observe a simple UITableView populated with data, all created programmatically without the use of storyboards.


Enhancing with a Custom Cell:

To take your UITableView to the next level, consider using a custom cell for a more personalized appearance. In our example, we've created a YourCustomCell class that inherits from UITableViewCell. This custom cell allows you to tailor the cell layout and appearance to match your app's design.


Here's a quick overview of the steps:


Create YourCustomCell Class:

import UIKit 

class YourCustomCell: UITableViewCell { 

   private let customLabel: UILabel = { 
      let label = UILabel() 
      label.translatesAutoresizingMaskIntoConstraints = false 
      return label 
   }() 
   
   overrideinit(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 
      super.init(style: style, reuseIdentifier: reuseIdentifier)    
      setupUI() 
   } 
   
   required init?(coder: NSCoder) {
      fatalError("init(coder:) has not been implemented") 
   } 
    
   func configure(with text: String) { 
      customLabel.text = text 
   } 
   
   private func setupUI() { 
      // Add the label to the cell's content view    
      contentView.addSubview(customLabel) 
      
      // Set up constraints for the label 
      NSLayoutConstraint.activate([ 
         customLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8), 
         customLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16), 
         customLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16), 
         customLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8) 
      ]) 
   } 
}

Update YourViewController:

// Register your custom cell class
tableView.register(YourCustomCell.self, forCellReuseIdentifier: "YourCellIdentifier") 

// Dequeue your custom cell 
let cell =  tableView.dequeueReusableCell(withIdentifier: "YourCellIdentifier", for: indexPath) as! YourCustomCell

The entire ViewController will now look like this:


Now, update the YourViewController to use the custom cell:

import UIKit 

class YourViewController: UIViewController { 

   var tableView: UITableView = {
      let tableView = UITableView() 
      tableView.translatesAutoresizingMaskIntoConstraints = false
      return tableView 
   }() 
   var viewModel: YourViewModel 
   
   init(viewModel: YourViewModel) {
      self.viewModel = viewModel 
      super.init(nibName: nil, bundle: nil) 
   } 
   
   
   required init?(coder: NSCoder) { 
      fatalError("init(coder:) has not been implemented") 
   } 
   
   override func viewDidLoad() { 
      super.viewDidLoad() 
      view.backgroundColor = .white 
      setupTableView() 
   }
   
   private func setupTableView() { 
      view.addSubview(tableView) 
      
      NSLayoutConstraint.activate([ 
         tableView.topAnchor.constraint(equalTo: view.topAnchor), 
         tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), 
         tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), 
         tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) 
         
         // Register your custom cell class 
         tableView.register(YourCustomCell.self, forCellReuseIdentifier: "YourCellIdentifier") 
         tableView.delegate = self 
         tableView.dataSource = self 
      } 
   } 
         
extension YourViewController: UITableViewDataSource { 
   func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
      return viewModel.data.count 
   } 
   
   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
      // Dequeue your custom cell 
      let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellIdentifier", for: indexPath) as! YourCustomCell 
      cell.configure(with: viewModel.data[indexPath.row]) 
      return cell 
   } 
}

extension YourViewController: UITableViewDelegate { 
   // Implement UITableViewDelegate methods as needed 
}


By incorporating a custom cell, you gain greater control over the visual presentation of each table view cell, allowing you to create a more polished and unique user interface.


You've successfully set up a UITableView in Swift, leveraging a ViewModel and creating the entire UI programmatically. This approach enhances code maintainability and scalability. Feel free to extend the functionality by incorporating additional UITableViewDelegate methods for handling row selection or exploring customization options. Happy coding!

2 views0 comments

Comments


bottom of page