Creating Alphabetical Section Headers in iOSUITableView Using Swift

Creating Alphabetical Section Headers in UITableView

Overview

In this article, we will explore how to create an alphabetical section header in a UITableView. We will go through the steps to achieve this, including understanding the concept of sections and rows, and implementing the necessary code.

Understanding Sections and Rows

A UITableView is divided into two main components: sections and rows. A section represents a group of related data, while a row represents an individual item within that section.

In our case, we have a dictionary sections that stores the contacts. Each key in the dictionary corresponds to a section, and its value is an array of contact names. When we retrieve the contacts from the database, we store them in this dictionary.

Section Headers

A section header is a view that appears at the top of each section. It typically displays the section title or some other relevant information. In our case, we want to display the section title alphabetically sorted.

Problem Statement

The problem we’re facing is that when we select a row in a particular section, it navigates to the details page for the corresponding contact. However, this doesn’t work as expected because of how we’ve implemented the sections and rows.

Section Implementation

Let’s take a closer look at how we implement sections:

sections = [[NSMutableDictionary alloc] init]; ///Global Object

BOOL found;

for (NSString *temp in contactsArray)
{        
    NSString *c = [temp substringToIndex:1];

    found = NO;

    for (NSString *str in [sections allKeys])
    {
        if ([str isEqualToString:c])
        {
            found = YES;
        }
    }

    if (!found)
    {     
        [sections setValue:[[NSMutableArray alloc] init] forKey:c];
    }
}

for (NSString *temp in contactsArray)
{
    [[sections objectForKey:[temp substringToIndex:1]] addObject:temp];
}

In this code, we first create a dictionary sections and then iterate through the contact names. If a section doesn’t exist, we create it and add the corresponding contact name to it.

Section Sorting

Now that we have our sections implemented, let’s sort them alphabetically:

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [[sections allKeys] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [[sections valueForKey:[[[sections allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] objectAtIndex:section]] count];
}

In this code, we’re using the sortedArrayUsingSelector method to sort the section keys alphabetically. We then use this sorted array to retrieve the corresponding contact names.

Section Headers with DetailTextLabel

Now that we have our sections and rows sorted, let’s implement the section headers with detail text label:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
    NSString *titleText = [[sections valueForKey:[[[sections allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];

    cell.textLabel.text = titleText;

    Contact *contact = [storedContactsArray objectAtIndex:indexPath.row];
    Contact *contactPicture = [storedPicsArray objectAtIndex:indexPath.row];

    cell.detailTextLabel.text = contact.companyName;

    UIImage *contactImage = [[UIImage alloc] initWithContentsOfFile:contactPicture.contactImage];
    cell.imageView.image = contactImage;
    return cell;
}

In this code, we’re setting the detail text label to contact.companyName and displaying the corresponding image.

Section Headers with Images

Let’s now implement section headers with images:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
    NSString *titleText = [[sections valueForKey:[[[sections allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];

    cell.textLabel.text = titleText;

    Contact *contact = [storedContactsArray objectAtIndex:indexPath.row];
    Contact *contactPicture = [storedPicsArray objectAtIndex:indexPath.row];

    UIImage *contactImage = [[UIImage alloc] initWithContentsOfFile:contactPicture.contactImage];
    cell.imageView.image = contactImage;
    return cell;
}

In this code, we’re setting the detail text label to an empty string and displaying the corresponding image.

Section Headers with didSelectRow

Finally, let’s implement section headers with didSelectRowAtIndexPath:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    EditContact *editContact = [[EditContact alloc] init];
    if([self.storedContactsArray count] != 0) {
        Contact *contactsDict = [storedContactsArray objectAtIndex:indexPath.row];
        editContact.contactInfo = contactsDict;

        Contact *picsDict = [storedPicsArray objectAtIndex:indexPath.row];
        editContact.storedPicsDict = picsDict;
    }

    [self.navigationController pushViewController:editContact animated:YES];
    [editContact release];
    [storedContactsArray release];
}

In this code, we’re selecting the row and pushing it to the navigation stack.

Conclusion

In this article, we’ve explored how to create an alphabetical section header in a UITableView. We’ve implemented sections, rows, and detail text labels, as well as images and didSelectRowAtIndexPath. By following these steps, you can achieve your goal of creating a customizable table view with alphabetical section headers.


Last modified on 2025-04-06