In the realm of table structures, an indexed table shares its essence with a regular table but distinguishes itself by sporting an index running vertically along its right edge. Typically, this index showcases letters or numbers, allowing users to tap them for an instant scroll to the pertinent section. In this tutorial, we will showcase various car brands within a table view, with the initial letter of each brand serving as the indexing criterion. This tutorial is crafted using Xcode 9 and tailored for iOS 11.

1. Begin by launching Xcode and initiating a new Single View App.

  •  For the product name, employ “IOS11IndexedTableViewTutorial,” and fill out the Organization Name and Organization Identifier with your standard values;
  • Opt for Swift as the programming language and proceed to the next step.

2. Navigate to the storyboard

To sculpt the desired interface, remove the View Controller and introduce a Navigation Controller into the Scene. This addition will also include a Table View Controller. Select the Navigation Controller, and within the Attribute Inspector, affirm the “Is Initial View Controller” checkbox.

3. Turn your attention to the Table View Cell

In the Attributes Inspector, you should designate the Identifier as “Cell.”

4. Your storyboard should now resemble this layout.

5. Safely eliminate the ViewController.swift 

As the View Controller has been removed from the Storyboard, you can safely eliminate the ViewController.swift file from the project. Add a new file to the project, selecting iOS -> Source -> Cocoa Touch Class. Name this new class “TableViewController” and ensure it inherits from UITableViewController.

6. Forge a connection 

Forge a connection between the TableViewController class and the Table View Controller object in the Storyboard. Select the Table View Controller, head to the Identity Inspector, and modify the class to “TableViewController.”

7. In TableViewController.swift, establish the following properties:

```swift
   var carsDictionary = [String: [String]]()
   var carSectionTitles = [String]()
   var cars = [String]()
   ```

8. Populate the “cars” array within the ViewDidLoad method with some sample data:

```swift
   override func viewDidLoad() {
       super.viewDidLoad()

       cars = ["Audi", "Aston Martin", "BMW", "Bugatti", "Bentley", "Chevrolet", "Cadillac", "Dodge", "Ferrari", "Ford", "Honda", "Jaguar", "Lamborghini", "Mercedes", "Mazda", "Nissan", "Porsche", "Rolls Royce", "Toyota", "Volkswagen"]

       // 1
       for car in cars {
           let carKey = String(car.prefix(1))
           if var carValues = carsDictionary[carKey] {
               carValues.append(car)
               carsDictionary[carKey] = carValues
           } else {
               carsDictionary[carKey] = [car]
           }
       }

       // 2
       carSectionTitles = [String](carsDictionary.keys)
       carSectionTitles = carSectionTitles.sorted(by: { $0 < $1 })
   }
   ```

   Here, the initial letter of each car is extracted and used as a key in the “carsDictionary.” If the key already exists, the car is added to the respective array; otherwise, a new array is created. The keys in “carsDictionary” are sorted alphabetically.

9. Subsequently, adapt the delegate methods of TableViewController:

```swift
   override func numberOfSections(in tableView: UITableView) -> Int {
       // 1
       return carSectionTitles.count
   }

   override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
       // 2
       let carKey = carSectionTitles[section]
       if let carValues = carsDictionary[carKey] {
           return carValues.count
       }

       return 0
   }

   override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       // 3
       let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

       // Configure the cell...
       let carKey = carSectionTitles[indexPath.section]
       if let carValues = carsDictionary[carKey] {
           cell.textLabel?.text = carValues[indexPath.row]
       }

       return cell
   }
   ```
  • The “numberOfSections(in:)” method returns the number of items in the “carSectionTitles” array;
  • The “tableView(_:numberOfRowsInSection:)” method determines the number of rows based on the number of cars in each section;
  • For each section, the car name is assigned to the “text” property of the “textLabel” property of the current cell.

10. To exhibit header titles in each section, implement the “tableView(_:titleForHeaderInSection:)” method:

 ```swift
    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return carSectionTitles[section]
    }
    ```

11. To introduce an indexed table view, implement the “sectionIndexTitles(for:)” method:

```swift
    override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
        return carSectionTitles
    }
    ```

12. Now, compile and run the project. 

Upon selecting an index, you should witness the table view seamlessly navigating to the corresponding row. Creating an indexed table, similar to a conventional one but featuring a vertical index on the right, simplifies data navigation. This guide, tailored for Xcode 9 and iOS 11, demonstrates this concept using a list of car brands. Start by initiating a Single View App in Xcode, naming it “IOS11IndexedTableViewTutorial.” Design the user interface by removing the default View Controller and adding a Navigation Controller, which includes a Table View Controller. Mark the Navigation Controller as the “Is Initial View Controller.”

To wrap up 

Configure the Table View Cell with the identifier “Cell” in the Attributes Inspector. Replace the redundant ViewController.swift file with a new “TableViewController” file, a subclass of UITableViewController. In TableViewController.swift, declare properties like “carsDictionary,” “carSectionTitles,” and “cars.” Populate the “cars” array with car brands, organizing them into sections based on their initial letters in the “ViewDidLoad” method.

Delegate methods like “numberOfSections(in:),” “tableView(_:numberOfRowsInSection:),” and “tableView(_:cellForRowAt:)” handle the table’s structure and data. Section headers are added using “tableView(_:titleForHeaderInSection:),” and an index is introduced with “sectionIndexTitles(for:).”

Test the project by building and running it. Users can now effortlessly navigate the table, thanks to the index, making data access swift and efficient. This tutorial underscores the significance of thoughtful UI design and data organization in creating user-friendly iOS interfaces. Indexed tables excel in simplifying data access, making this guide invaluable for iOS developers seeking to implement this feature in their projects.

Leave a Reply