Let’s start creating a new project in Xcode. We will start with Single View Application Template. In Xcode go File->New-Project in the menu and choose a Single View Application template.
Fill in Product Name.

Then choose where your Xcode project will be stored.
Now in ViewController.swift class change base class from UIViewController to UITableViewController.

In Main.storyboard remove existing view controller from canvas.

Look at Object Library which is on bottom right. Find Table View Controller there. Drag it to the canvas and drop it there. In Attributes Inspector on the right turn on “Is Initial View Controller” check box.

In storyboard choose your view controller and in Identity Inspector enter ViewController as class name of the class.

Now if you Build and Run you will see empty table in simulator.

Choose cell in storyboard and fill in Identifier field in Attributes inspector. That’s cell reuse identifier which will be used in code.

Now let’s do some coding. In ViewController.swift add protocol UITableViewDataSource to class declaration. That means our class ViewController intends to implement some methods from protocol UITableViewDataSource.

Add array to the class. Array will be our data source.
var array = ["Moscow", "Saint Petersburg", "Novosibirsk", "Novosibirsk", "Nizhny Novgorod", "Samara", "Omsk", "Kiyv", "Odessa", "Donetsk", "Harkiv", "Lviv", "Uzhgorod", "Zhytomyr", "Luhansk", "Mikolayv", "Kherson", "Germany", "Berlin", "Hamburg", "Munich", "Cologne", "Frankfurt", "Stuttgart", "Düsseldorf", "Dortmund", "Essen", "Bremen", "Abilene", "Akron", "Albuquerque", "Alexandria", "Allentown", "Amarillo", "Anaheim", "Anchorage", "Ann Arbor", "Antioch", "Arlington", "Arvada", "Athens", "Atlanta", "Augusta", "Aurora", "Austin", "Bakersfield", "Baltimore", "Baton Rouge", "Beaumont", "Bellevue", "Berkeley", "Billings", "Birmingham", "Boise", "Boston", "Boulder", "Bridgeport", "Broken Arrow", "Brownsville", "Buffalo", "Burbank", "Cambridge", "Cape Coral", "Carlsbad", "Carrollton", "Cary", "Cedar Rapids", "Centennial", "Chandler", "Charleston", "Charlotte", "Chattanooga", "Chesapeake", "Chicago", "Chula Vista", "Cincinnati", "Clarksville", "Clearwater", "Cleveland", "College Station", "Colorado Springs", "Columbia", "Columbus", "Concord", "Coral Springs", "Corona", "Corpus Christi", "Costa Mesa", "Dallas", "Daly City", "Davenport", "Dayton", "Denton", "Denver", "Des Moines", "Detroit", "Downey", "Durham", "Edison", "El Cajon", "El Monte", "El Paso", "Elgin", "Elizabeth", "Elk Grove", "Erie", "Escondido", "Eugene", "Evansville", "Everett", "Fairfield", "Fargo", "Fayetteville", "Fontana", "Fort Collins", "Fort Lauderdale", "Fort Wayne", "Fort Worth", "Fremont", "Fresno", "Frisco", "Fullerton", "Gainesville", "Garden Grove", "Garland", "Gilbert", "Glendale", "Grand Prairie", "Grand Rapids", "Green Bay", "Greensboro", "Gresham", "Hampton", "Hartford", "Hayward", "Henderson", "Hialeah", "High Point", "Hollywood", "Honolulu", "Houston", "Huntington Beach", "Huntsville", "Independence", "Indianapolis", "Inglewood", "Irvine", "Irving", "Jackson", "Jacksonville", "Jersey City", "Joliet", "Kansas City", "Kent", "Killeen", "Knoxville", "Lafayette", "Lakeland", "Lakewood", "Lancaster", "Lansing", "Laredo", "Las Cruces", "Las Vegas", "Lewisville", "Lexington", "Lincoln", "Little Rock", "Long Beach", "Los Angeles", "Louisville", "Lowell", "Lubbock", "Madison", "Manchester", "McAllen", "McKinney", "Memphis", "Mesa", "Mesquite", "Miami", "Miami Gardens", "Midland", "Milwaukee", "Minneapolis", "Miramar", "Mobile", "Modesto", "Montgomery", "Moreno Valley", "Murfreesboro", "Murrieta", "Naperville", "Nashville", "New Haven", "New Orleans", "New York", "Newark", "Newport News", "Norfolk", "Norman", "North Charleston", "North Las Vegas", "Norwalk", "Oakland", "Oceanside", "Oklahoma City", "Olathe", "Omaha", "Ontario", "Orange", "Orlando", "Overland Park", "Oxnard", "Palm Bay", "Palmdale", "Pasadena", "Paterson", "Pearland", "Pembroke Pines", "Peoria", "Peoria", "Philadelphia", "Phoenix", "Pittsburgh", "Plano", "Pomona", "Pompano Beach", "Port St. Lucie", "Portland", "Providence", "Provo", "Pueblo", "Raleigh", "Rancho Cucamonga", "Reno", "Rialto", "Richardson", "Richmond", "Riverside", "Rochester", "Rockford", "Roseville", "Round Rock", "Sacramento", "Saint Paul", "Salem", "Salinas", "Salt Lake City", "San Antonio", "San Bernardino", "San Diego", "San Francisco", "San Jose", "San Mateo", "Santa Ana", "Santa Clara", "Santa Clarita", "Santa Maria", "Santa Rosa", "Savannah", "Scottsdale", "Seattle", "Shreveport", "Simi Valley", "Sioux Falls", "South Bend", "Spokane", "Springfield", "St. Louis", "St. Petersburg", "Stamford", "Sterling Heights", "Stockton", "Sunnyvale", "Surprise", "Syracuse", "Tacoma", "Tallahassee", "Tampa", "Temecula", "Tempe", "Thornton", "Thousand Oaks", "Toledo", "Topeka", "Torrance", "Tucson", "Tulsa", "Tyler", "Vallejo", "Vancouver", "Ventura", "Victorville", "Virginia Beach", "Visalia", "Waco", "Warren", "Washington", "Waterbury", "West Covina", "West Jordan", "West Palm Beach", "West Valley City", "Westminster", "Wichita", "Wichita Falls", "Wilmington", "Winston–Salem", "Woodbridge", "Worcester", "Yonkers", "York"]
This array is array of strings which we will display in our table. Array is quite big. To make navigating through table easier we are willing to order it and display cells grouped in sections according to their first letter.
Add this line to viewDidLoad method to sort array to it’s alphabetical order:
array.sort { $0 < $1 }
Now we have to split this array on groups of elements, each will be displayed in separate section of table view. We won’t split array literally but just bring into play another supplementary array which will help us to remember where each section starts, how many elements are in a section and what title of a section is.
var sections : [(index: Int, length :Int, title: String)] = Array()
Elements of this array are tuples, special Swift type. Tuple has a number of named elements. index is index in array array of first element of section. length is number of elements in section. And title is one character string which will be used for section title in table view.
Now we have to build this array. Add code below to viewDidLoad method just under sorting line:
var index = 0;
for ( var i = 0; i < array.count; i++ ) {
let commonPrefix = array[i].commonPrefixWithString(array[index], options: .CaseInsensitiveSearch)
if (countElements(commonPrefix) == 0 ) {
let string = array[index].uppercaseString;
let firstCharacter = string[string.startIndex]
let title = "\(firstCharacter)"
let newSection = (index: index, length: i - index, title: title)
sections.append(newSection)
index = i;
}
}
We traverse through array beginning from the first element. Inside of for loop we look for common prefix of elements in array array with indexes i and index. If these strings don’t have common index, that means we have finished with section. We make new tuple and insert it into array sections. Then we remember where next section starts and repeat loop.
Lets implement UITableViewDataSource protocol methods. numberOfSectionsInTableView returns number of sections in table. In will be count of our sections array.
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sections.count
}
numberOfRowsInSection returns number of rows in particular section. We take this from sections array.
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].length
}
And cellForRowAtIndexPath makes cell and fills it with data.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell;
cell.textLabel?.text = array[sections[indexPath.section].index + indexPath.row]
return cell
}
To make index work we need to implement another three methods. titleForHeaderInSection will return appropriate title of the section. We get title from sections array:
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String {
return sections[section].title
}
sectionIndexTitlesForTableView should return array of all section titles. We have all section titles in sections array. To make new array with titles only we use map function:
override func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]! {
return sections.map { $0.title }
}
sectionForSectionIndexTitle returns section number. In our case it will be index parameter of this method.
override func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
return index
}

Build and Run and see table view with index.

To make app a little bit neat we can make table view go just below status bar. There are different ways of doing that. Most simple way – just embed table view controller into navigation controller. To do that choose ViewController in canvas. Then go in menu Editor -> Embed In -> Navigation Controller:

Build and run:

That’s it.