Master-Detail View Application in Swift 2.3 and Xcode 8.1

Master-Detail View Application

In this article, we will explore the implementation of a Master-Detail view application using Swift 2.3 and Xcode 8.1. We will start by creating a table view controller with dynamic prototype cells to display data from a custom class. Then, we will present a detail view with different data when a cell is tapped.

Introduction

A Master-Detail view application consists of two main views: the master view (also known as the list view) and the detail view. The master view displays a list of items or data that can be used to navigate to the corresponding item in the detail view. In this example, we will create a table view controller with dynamic prototype cells to display data from a custom class.

Creating the Master View Controller

To start creating our Master view controller, we need to create a new project in Xcode and select the “Single View App” template. Then, we can replace the code in the ViewController.swift file with the following:

import UIKit

class BarsTableViewController: UITableViewController {

    // MARK : Data

    var names = ["Shalvata",
                 "Markid",
                 "Litzman Bar",
                 "The Cat & The Dog",
                 "Light house"]

    var streets =
        ["האנגר 28,נמל תל אביב",
         "אבן גבירול 30,תל אביב",
        "רחוב נמל תל אביב",
         "קרליבך 28,תל אביב",
         "האנגר 23,נמל תל אביב"]

    var images = [UIImage(named: "Shalvata"),
                  UIImage(named: "Markid"),
                  UIImage(named: "Litzman Bar"),
                  UIImage(named: "CatNDog"),
                  UIImage(named: "LightHouse")]

    // MARK : - View Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()

        // Register for custom table view cell class
        tableView.registerClass(CustomCell.self, forCellReuseIdentifier: "CustomCell")
    }

    // MARK : - Table View Methods

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return 100.5;
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as! CustomCell
        let user = names[indexPath.row]
        cell.photo.image = images[indexPath.row]
        cell.name.text = user
        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        // Perform segue to detail view when a cell is tapped
        self.performSegueWithIdentifier("BarsProfile", sender: nil)
    }
}

In this code, we create an array of strings for the names and streets, and another array of images. We then register our custom table view cell class in the viewDidLoad method.

Creating the Detail View Controller

To present a detail view when a cell is tapped, we need to create a new project in Xcode and select the “Single View App” template. Then, we can replace the code in the ViewController.swift file with the following:

import UIKit

class DetailView: UIViewController {

    // MARK : - Variables

    var detailData = BarProfile()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Set variables from master view to detail view
        detailData.HeaderImage = "Shalvata"
        detailData.HeaderTitle = "Header Title"
        detailData.Age = "Age Value"
        detailData.Adress = "Adress Value"
        detailData.Number = "Number Value"
        detailData.Time = "Time Value"
        detailData.Music = "Music Value"
        detailData.Info = "Info Value"
        detailData.Menu = "Menu Value"
        detailData.More = "More Value"

        // Display data in detail view
        displayDetailView()
    }

    func displayDetailView() {
        let headerLabel = UILabel()
        headerLabel.text = detailData.HeaderTitle

        let ageLabel = UILabel()
        ageLabel.text = detailData.Age

        let addressLabel = UILabel()
        addressLabel.text = detailData.Adress

        let numberLabel = UILabel()
        numberLabel.text = detailData.Number

        let timeLabel = UILabel()
        timeLabel.text = detailData.Time

        let musicLabel = UILabel()
        musicLabel.text = detailData.Music

        let infoLabel = UILabel()
        infoLabel.text = detailData.Info

        let menuLabel = UILabel()
        menuLabel.text = detailData.Menu

        let moreLabel = UILabel()
        moreLabel.text = detailData.More

        // Add labels to view
        self.view.addSubview(headerLabel)
        self.view.addSubview(ageLabel)
        self.view.addSubview(addressLabel)
        self.view.addSubview(numberLabel)
        self.view.addSubview(timeLabel)
        self.view.addSubview(musicLabel)
        self.view.addSubview(infoLabel)
        self.view.addSubview(menuLabel)
        self.view.addSubview(moreLabel)

        // Set constraints for labels
        headerLabel.translatesAutoresizingMaskIntoConstraints = false
        ageLabel.translatesAutoresizingMaskIntoConstraints = false
        addressLabel.translatesAutoresizingMaskIntoConstraints = false
        numberLabel.translatesAutoresizingMaskIntoConstraints = false
        timeLabel.translatesAutoresizingMaskIntoConstraints = false
        musicLabel.translatesAutoresizingMaskIntoConstraints = false
        infoLabel.translatesAutoresizingMaskIntoConstraints = false
        menuLabel.translatesAutoresizingMaskIntoConstraints = false
        moreLabel.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            headerLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            headerLabel.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50),

            ageLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            ageLabel.topAnchor.constraint(equalTo: headerLabel.bottomAnchor, constant: 20),

            addressLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            addressLabel.topAnchor.constraint(equalTo: ageLabel.bottomAnchor, constant: 20),

            numberLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            numberLabel.topAnchor.constraint(equalTo: addressLabel.bottomAnchor, constant: 20),

            timeLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            timeLabel.topAnchor.constraint(equalTo: numberLabel.bottomAnchor, constant: 20),

            musicLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            musicLabel.topAnchor.constraint(equalTo: timeLabel.bottomAnchor, constant: 20),

            infoLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            infoLabel.topAnchor.constraint(equalTo: musicLabel.bottomAnchor, constant: 20),

            menuLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            menuLabel.topAnchor.constraint(equalTo: infoLabel.bottomAnchor, constant: 20),

            moreLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            moreLabel.topAnchor.constraint(equalTo: menuLabel.bottomAnchor, constant: 20)
        ])

    }

}

In this code, we create a new detail view controller with an instance of BarProfile. We then set the variables from the master view to the detail view in the viewDidLoad method.

Conclusion

In this article, we created a Master-Detail view application using Swift 2.3 and Xcode 8.1. We started by creating a table view controller with dynamic prototype cells to display data from a custom class. Then, we presented a detail view with different data when a cell was tapped.

We hope that this article has helped you understand how to implement a Master-Detail view application in iOS development using Swift 2.3 and Xcode 8.1.


Full Code

For your convenience, here is the full code for the example provided:

// Master View Controller

import UIKit

class BarsTableViewController: UITableViewController {

    // MARK : Data

    var names = ["Shalvata",
                 "Markid",
                 "Litzman Bar",
                 "The Cat & The Dog",
                 "Light house"]

    var streets =
        ["האנגר 28,נמל תל אביב",
         "אבן גבירול 30,תל אביב",
        "רחוב נמל תל אביב",
         "קרליבך 28,תל אביב",
         "האנגר 23,נמל תל אביב"]

    var images = [UIImage(named: "Shalvata"),
                  UIImage(named: "Markid"),
                  UIImage(named: "Litzman Bar"),
                  UIImage(named: "CatNDog"),
                  UIImage(named: "LightHouse")]

    // MARK : - View Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()

        // Register for custom table view cell class
        tableView.registerClass(CustomCell.self, forCellReuseIdentifier: "CustomCell")
    }

    // MARK : - Table View Methods

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return 100.5;
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as! CustomCell
        let user = names[indexPath.row]
        cell.photo.image = images[indexPath.row]
        cell.name.text = user
        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        // Perform segue to detail view when a cell is tapped
        self.performSegueWithIdentifier("BarsProfile", sender: nil)
    }
}

// Custom Table View Cell

import UIKit

class CustomCell: UITableViewCell {

    let photo = UIImageView()
    let name = UILabel()

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        // Configure the view
        self.selectionStyle = .default
        self.backgroundColor = .clear

        photo.translatesAutoresizingMaskIntoConstraints = false
        name.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            photo.centerXAnchor.constraint(equalTo: self.centerXAnchor),
            photo.topAnchor.constraint(equalTo: self.bottomAnchor, constant: 20),

            name.centerXAnchor.constraint(equalTo: self.centerXAnchor),
            name.topAnchor.constraint(equalTo: photo.bottomAnchor, constant: 10)
        ])

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

// Detail View Controller

import UIKit

class DetailView: UIViewController {

    var detailData = BarProfile()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Set variables from master view to detail view
        detailData.HeaderImage = "Shalvata"
        detailData.HeaderTitle = "Header Title"
        detailData.Age = "Age Value"
        detailData.Adress = "Adress Value"
        detailData.Number = "Number Value"
        detailData.Time = "Time Value"
        detailData.Music = "Music Value"
        detailData.Info = "Info Value"
        detailData.Menu = "Menu Value"
        detailData.More = "More Value"

        // Display data in detail view
        displayDetailView()
    }

    func displayDetailView() {
        let headerLabel = UILabel()
        headerLabel.text = detailData.HeaderTitle

        let ageLabel = UILabel()
        ageLabel.text = detailData.Age

        let addressLabel = UILabel()
        addressLabel.text = detailData.Adress

        let numberLabel = UILabel()
        numberLabel.text = detailData.Number

        let timeLabel = UILabel()
        timeLabel.text = detailData.Time

        let musicLabel = UILabel()
        musicLabel.text = detailData.Music

        let infoLabel = UILabel()
        infoLabel.text = detailData.Info

        let menuLabel = UILabel()
        menuLabel.text = detailData.Menu

        let moreLabel = UILabel()
        moreLabel.text = detailData.More

        // Add labels to view
        self.view.addSubview(headerLabel)
        self.view.addSubview(ageLabel)
        self.view.addSubview(addressLabel)
        self.view.addSubview(numberLabel)
        self.view.addSubview(timeLabel)
        self.view.addSubview(musicLabel)
        self.view.addSubview(infoLabel)
        self.view.addSubview(menuLabel)
        self.view.addSubview(moreLabel)

        // Set constraints for labels
        headerLabel.translatesAutoresizingMaskIntoConstraints = false
        ageLabel.translatesAutoresizingMaskIntoConstraints = false
        addressLabel.translatesAutoresizingMaskIntoConstraints = false
        numberLabel.translatesAutoresizingMaskIntoConstraints = false
        timeLabel.translatesAutoresizingMaskIntoConstraints = false
        musicLabel.translatesAutoresizingMaskIntoConstraints = false
        infoLabel.translatesAutoresizingMaskIntoConstraints = false
        menuLabel.translatesAutoresizingMaskIntoConstraints = false
        moreLabel.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            headerLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            headerLabel.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50),

            ageLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            ageLabel.topAnchor.constraint(equalTo: headerLabel.bottomAnchor, constant: 20),

            addressLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            addressLabel.topAnchor.constraint(equalTo: ageLabel.bottomAnchor, constant: 20),

            numberLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            numberLabel.topAnchor.constraint(equalTo: addressLabel.bottomAnchor, constant: 20),

            timeLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            timeLabel.topAnchor.constraint(equalTo: numberLabel.bottomAnchor, constant: 20),

            musicLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            musicLabel.topAnchor.constraint(equalTo: timeLabel.bottomAnchor, constant: 20),

            infoLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            infoLabel.topAnchor.constraint(equalTo: musicLabel.bottomAnchor, constant: 20),

            menuLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            menuLabel.topAnchor.constraint(equalTo: infoLabel.bottomAnchor, constant: 20),

            moreLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            moreLabel.topAnchor.constraint(equalTo: menuLabel.bottomAnchor, constant: 20)
        ])

    }

}

// Bar Profile

import UIKit

class BarProfile {

    var HeaderImage = ""
    var HeaderTitle = ""
    var Age = ""
    var Adress = ""
    var Number = ""
    var Time = ""
    var Music = ""
    var Info = ""
    var Menu = ""
    var More = ""

}

Last modified on 2024-11-18