iOS 9: Beyond the first look

Get all subviews

let childViews = view.subviews

for aView in childViews {
    if aView is UILabel {
        let aLabel = aView as UILabel
    } else if aView is UIButton {
        let aButton = aView as UIButton
    } else if aView is UIImageView {
        let aImageView = aView as UIImageView

Table views

  • iOS table view is one column wide (with multiple rows)
  • One row contains one cell. This cell contains the views of that particular row

Let’s create a simple tableview

  1. Drag a Table View (not Table View Controller) into your main view controller.
  2. Resolve auto layout issues (Select Table View => Editor => Resolve Auto Layout Issues => Reset to Suggested Constraints)
  3. Connect dataSource and delegate Outlets to view controller (from Connections Inspector)

UITableViewDataSource controls the following

  • Configuring a table view
  • Inserting or deleting table rows
  • Reordering table rows

Configuring a table view

There are several methods you can use to configure your table view. Look at the apple documentation for elaborated information. For a quick overview look at the list

– tableView:cellForRowAtIndexPath: (Required)
Asks the data source for a cell to insert in a particular location of the table view.

func tableView(_ tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath)
-> UITableViewCell

– tableView:numberOfRowsInSection: (Required)
Tells the data source to return the number of rows in a given section of a table view.

func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int

– numberOfSectionsInTableView:
Asks the data source to return the number of sections in the table view.

optional func numberOfSectionsInTableView
(_ tableView: UITableView) -> Int

Implementation of the required methods

class ViewController: UIViewController, UITableViewDataSource {

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel!.text = "Cell number \(indexPath.row)"

        return cell

Now we will create some dummy data and make use of the tableview accordingly

class ViewController: UIViewController, UITableViewDataSource {

    let section1Data = ["Section 1a", "Section 1b", "Section 1c", "Section 1d"]
    let section2Data = ["Section 2a", "Section 2b", "Section 2c", "Section 2d", "Section 2e"]
    let section3Data = ["Section 3a", "Section 3b", "Section 3c"]

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 3

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch section {
        case 0: return section1Data.count
        case 1: return section2Data.count
        case 2: return section3Data.count
        default: return 0

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = UITableViewCell()

        var item : String

        switch indexPath.section {
        case 0:
            item = section1Data [indexPath.row]
        case 1:
            item = section2Data [indexPath.row]
        case 2:
            item = section3Data [indexPath.row]
            item = ""

        cell.textLabel!.text = item

        return cell

    func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        switch section {
        case 0:
            return "Section 01"
        case 1:
            return "Section 02"
        case 2:
            return "Section 03"
            return ""

    override func viewDidLoad() {
        // Do any additional setup after loading the view, typically from a nib.

    override func didReceiveMemoryWarning() {
        // Dispose of any resources that can be recreated.

UITableViewDelegate controls the following

  • Behaviour
  • Appearance
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {


    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        print("User clicked. Section \(indexPath.section) and row \(indexPath.row)")

    func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
        let deleteAction = UITableViewRowAction(style: .Default, title: "Delete", handler: {
            action, indexPath in
            // Delete from data
            switch indexPath.section {
            case 0:
            case 1:
            case 2:
            tableView.editing = false
        let retActions = [deleteAction]
        return retActions


Alert view

let confirmAlert = UIAlertController(title: "Deleting row", message: "Do you really want to delete?", preferredStyle: .Alert)
let posAction = UIAlertAction(title: "Yes", style: .Destructive, handler: {
    action in
    print("Yes button clicked")
let negAction = UIAlertAction(title: "No", style: .Default, handler: nil)
presentViewController(confirmAlert, animated: true, completion: nil)

Add App icon

  • Select Assets.xcassets -> AppIcon -> Attirbutes Inspector
  • You should see all possible image sizes you would like to provide
  • Select each of the icon and see the Image section in Attirbutes Inspector
  • You will see the Size property, but it is in point mode, not pixel. Then you will see the Scale property and know the actual pixel sized image you need to provide. px = pt * scale

Launcher screen

  • Usually launcher screen would be the first screen of the application without any data loaded.
  • You can mimic the controls of the first screen and put those is same fashion in launcher screen.

For more informaiton, follow this guide

Add a new ViewController

  • Add a new ViewController (or, variant) in storyboard
  • Create a new Cocoa Touch Class (Swift file), make it a subclass of UIViewController (or, variant)
  • Select the ViewController from storyboard and open Identity Inspector and link with the Swift file
  • Now we need to make a way to go to the new screen. Let’s review show method first.
    • Create a button in FirstViewController and Control+Drag it to the SecondViewController and select Action Segue (Show)
  • Another way is to create a NavigationViewController.
    • Select the FirstViewController and Editor => Embed In => Navigation Controller
    • For displaying a title, go to viewDidLoad() method and override self.title = “”

Add a new TabbarController

  • We can start by opening a new project with Tabbed Application option
  • Create a new ViewController in storyboard and control+drag from TabbarController (bottom) to new ViewController
  • This time select Relationship Segues (view controllers)
  • Individual tabbar icon or text can be change by selecting that individual tab text/icon.

Auto Layout and handling multiple screens

  • Auto Layout is enabled by default. Still if you need to check, Open storyboard => Show File Inspector => Check (Use Auto Layout)
  • First place the controls in square sized view controller and then make use of Resolve Auto Layout Issues (Bottom-Right corner) => Reset to Suggessted Constraints
  • General suggestion: If you get yellow/red sign in Auto Layout then go to Document Outline screen of storyboard and tap on the top right corner button
  • Clear constraint of a paritcular view by selecting Resolve Auto Layout Issues (Bottom-Right corner) => Clear Constraints
  • For more info:
  • Alternatively you can use a handy library:

Stack Views

  • Stack views are much more like LinearLayout in Android. They can either be horizontal or vertical. Unlike LinearLayout they can NOT have any view properties (color etc)
  • Unlike Android, you are supposed to use nested stack views in iOS
  • There are 3 properties in stack views that you need to take care of
    • Alignment
    • Distribution
    • Spacing
  • General suggestion: First place controls roughly on the storyboard
    • Select the controls
    • Editor -> Embed In -> Stack view
    • Xcode should embed the controls with proper subviews. If not you can change it from Attributes Inspector.
  • Selecting stack view from storyboard can be tricky. Also, dragging the stack view to setup it’s width and height will not work as expected. Workaround is, select stack view from Document Outline view. Setup constraint using Pin button (Bottom-right corner)
  • Now play with the 3 attributes (Alignment, Distribution and Spacing) from Attributes Inspector to make things right your choice.
  • You might see some warnings regarding stack views and those might be a false alarm. Select the stack view, go to the Size Inspector and decrement the value of x by one and change it back to original. If it was a false alarm it should go away.

Dynamic layout for different screens

You can take advantage of size classes as it will allow you to design specific layout for specific screen. For example, you can reduce the font size only when the layout will render in iPhone 4 landscape mode. Remember, Auto layout constraints will be applied first than Size classes.

You should see “w any h Any” at the bottom of the storyboard. Tap on it and select a variation. At the bottm of the new dialog you can see the list of the screen this particular variation will take effect.

There are two keywords: Compact and Regular. Here, Compact essentially means, limited. You need to take extra care when you see compact width/height.

For more information, follow this guide

General suggestion: You should play with the size classes at the very end. In addition, you should do the experiments in separate branch, thus you can always revert back to the previous working branch.

After selecting a variant the bottom bar of the storyboard will turn into blue and the storyboard view controller will take the specific device frame that you selected in variant.

Change the font

  • Select the label.
  • Go to Attributes Inspector
  • Do not change the font. Instead, click on the (+) button beside font.
  • Select the proper variation base and you should see a separate font change inputbox
  • Change font and size using the input box.
  • Use Assistance Editor (Preview mode) to see how things will look finally in different devices

Change size of a view

  • Make sure the auto layout constraints have been set.
  • Select the control you would like to change the size.
  • Go to Size Inspector. In the Constraints section, change the constraint value (width/height) by clicked Edit button
  • Check your work in Assistance Editor (Preview mode)
  • You might need to set the auto layout contraints again based on the changes you made

Remove a view/item

  • Select the control you would like to delete.
  • Hit Command + Delete.
  • The control should still be visible in Document Outline view but greyed out

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s