Hooking Up the Content

To display the information for the selected Item, you will need to create a new UIViewController subclass.

Create a new Swift file and name it DetailViewController. Open DetailViewController.swift and declare a new UIViewController subclass named DetailViewController.

Listing 11.1  Creating the DetailViewController class (DetailViewController.swift)

import Foundation
import UIKit

class DetailViewController: UIViewController {

}

Because you need to be able to access the subviews you created during runtime, DetailViewController needs outlets for them. The plan is to add four new outlets to DetailViewController and then make the connections. In previous exercises, you did this in two distinct steps: First, you added the outlets in the Swift file, then you made connections in the storyboard file. You can do both at once by opening a second editor pane.

With DetailViewController.swift open, Option-click Main.storyboard in the project navigator. This will open the file in another editor next to DetailViewController.swift.

Before you connect the outlets, you need to tell the detail interface that it should be associated with the DetailViewController. Select the View Controller on the canvas and open its identity inspector. Change the Class to be DetailViewController (Figure 11.10).

Figure 11.10  Setting the view controller class

Setting the view controller class

Your window has become a little cluttered. Let’s make some temporary space. Hide the navigator area and inspector area by clicking the left and right button, respectively, in the View control at the top of the workspace. Then, hide the document outline in Interface Builder by clicking the toggle button in the lower-left corner of its editor. Your workspace should now look like Figure 11.11.

Figure 11.11  Laying out the workspace

Laying out the workspace

The three instances of UITextField and the bottom instance of UILabel will be outlets in DetailViewController. Control-drag from the UITextField next to the Name label to the top of DetailViewController.swift, as shown in Figure 11.12.

Figure 11.12  Dragging from storyboard to source file

Dragging from storyboard to source file

Let go and a pop-up window will appear. Enter nameField into the Name field, make sure the Storage is set to Strong, and click Connect (Figure 11.13).

Figure 11.13  Autogenerating an outlet and making a connection

Autogenerating an outlet and making a connection

This will create an @IBOutlet property of type UITextField named nameField in DetailViewController.

In addition, this UITextField is already connected to the nameField outlet of the DetailViewController. You can verify this by Control-clicking the Detail View Controller to see the connections. Also notice that hovering your mouse above the nameField connection in the panel that appears will reveal the UITextField that you connected. Two birds, one stone.

Create the other three outlets the same way and name them as shown in Figure 11.14.

Figure 11.14  Connection diagram

Connection diagram

After you make the connections, DetailViewController.swift should look like this:

    import UIKit

    class DetailViewController: UIViewController {

        @IBOutlet var nameField: UITextField!
        @IBOutlet var serialNumberField: UITextField!
        @IBOutlet var valueField: UITextField!
        @IBOutlet var dateLabel: UILabel!

    }

If your file looks different, then your outlets are not connected correctly. Fix any disparities between your file and the code shown above in three steps:

  • First, go through the Control-drag process and make connections again until you have the four lines shown above in your DetailViewController.swift.

  • Second, remove any wrong code (like non-property method declarations or properties) that got created.

  • Finally, check for any bad connections in the storyboard file – in Main.storyboard, Control-click on the Detail View Controller. If there are yellow warning signs next to any connection, click the Connection diagram icon next to those connections to disconnect them.

It is important to ensure that there are no bad connections in an interface file. A bad connection typically happens when you change the name of a property but do not update the connection in the interface file or when you completely remove a property but do not remove it from the interface file. Either way, a bad connection will cause your application to crash when the interface file is loaded.

With the connections made, you can close the additional editor by clicking the Connection diagram in the top-left corner and return to viewing just DetailViewController.swift.

DetailViewController will hold on to a reference to the Item that is being displayed. When its view is loaded, you will set the text on each text field to the appropriate value from the Item instance.

In DetailViewController.swift, add a property for an Item instance and override viewWillAppear(_:) to set up the interface.

Listing 11.2  Populating the interface with the Item values (DetailViewController.swift)

class DetailViewController: UIViewController {

    @IBOutlet var nameField: UITextField!
    @IBOutlet var serialNumberField: UITextField!
    @IBOutlet var valueField: UITextField!
    @IBOutlet var dateLabel: UILabel!

    var item: Item!

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        nameField.text = item.name
        serialNumberField.text = item.serialNumber
        valueField.text = "(item.valueInDollars)"
        dateLabel.text = "(item.dateCreated)"
    }
}

This works, but instead of using string interpolation to print out the valueInDollars and dateCreated, it would be better to use a formatter. You used an instance of NumberFormatter in Chapter 6. You will use another one here, as well as an instance of DateFormatter to format the dateCreated.

Add an instance of NumberFormatter and an instance of DateFormatter to the DetailViewController. Use these formatters in viewWillAppear(_:) to format the valueInDollars and dateCreated.

Listing 11.3  Adding and using data formatters (DetailViewController.swift)

var item: Item!

let numberFormatter: NumberFormatter = {
    let formatter = NumberFormatter()
    formatter.numberStyle = .decimal
    formatter.minimumFractionDigits = 2
    formatter.maximumFractionDigits = 2
    return formatter
}()

let dateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateStyle = .medium
    formatter.timeStyle = .none
    return formatter
}()

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    nameField.text = item.name
    serialNumberField.text = item.serialNumber
    valueField.text = "(item.valueInDollars)"
    dateLabel.text = "(item.dateCreated)"
    valueField.text =
        numberFormatter.string(from: NSNumber(value: item.valueInDollars))
    dateLabel.text = dateFormatter.string(from: item.dateCreated)
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset