Passing Data with Segues
Learn how to pass data between ViewControllers in Swift using Storyboard Segues, from a master view to a detail view.
Note:
This tutorial demonstrates how to handle row selection in a UITableView and pass the corresponding data to another UIViewController to display detailed information.
Overview
When a user taps an item in a UITableView, you often want to display more details on a new screen. A common example is in social media apps where tapping a post opens a detailed view with the image and comments. This is achieved by using Segues and passing data between UIViewControllers.
In this tutorial, we will build a simple app that displays a list of superhero names in a UITableView. When a user taps a name, a new UIViewController will appear, showing the superhero's name and image.
Reference:
Step 1: Setting up the Storyboard
Create TableView and Detail ViewController
- Open your
Main.storyboard. - Add a
UITableViewControllerto your storyboard. This will be our main screen. - Add a new
UIViewController. This will be our detail screen. - Create a new Swift file for your detail view controller, name it
DetailsViewController.swift.
- In the storyboard, select your new detail
UIViewController. Go to the Identity Inspector and set its custom class toDetailsViewController.
Create a Segue
- Control-drag from a cell in your
UITableViewControllerto theDetailsViewController. - Choose Show from the popup menu to create a segue.
- Select the segue and go to the Attributes Inspector. Give it an identifier, for example,
toDetailsVC.
Embed in Navigation Controller
To get a navigation bar with a back button, select your main UITableViewController and go to Editor > Embed In > Navigation Controller.
Step 2: Designing the Detail View
In your DetailsViewController on the storyboard, add a UIImageView and a UILabel. Connect them as outlets to your DetailsViewController.swift file.
// In DetailsViewController.swift
import UIKit
class DetailsViewController: UIViewController {
@IBOutlet weak var heroImageView: UIImageView!
@IBOutlet weak var heroNameLabel: UILabel!
var selectedHeroName: String?
var selectedHeroImageName: String?
override func viewDidLoad() {
super.viewDidLoad()
heroNameLabel.text = selectedHeroName
if let imageName = selectedHeroImageName {
heroImageView.image = UIImage(named: imageName)
}
}
}
Step 3: Populating the TableView
In your main ViewController.swift, set up the data and UITableViewDataSource methods.
Prepare the Data
First, add your images to the Assets.xcassets folder. Then, create arrays to hold your data.
// In ViewController.swift
var heroNames = [String]()
var heroImageNames = [String]()
var selectedName = ""
var selectedImage = ""
override func viewDidLoad() {
super.viewDidLoad()
// Populate data
heroNames.append("Batman")
heroNames.append("Superman")
heroNames.append("Iron Man")
heroImageNames.append("batman")
heroImageNames.append("superman")
heroImageNames.append("ironman")
}
TableView DataSource Methods
Implement the necessary UITableView methods.
// In ViewController.swift
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return heroNames.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = heroNames[indexPath.row]
return cell
}
Step 4: Passing Data with a Segue
Handle Row Selection
Use didSelectRowAt to detect a tap and trigger the segue.
// In ViewController.swift
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedName = heroNames[indexPath.row]
selectedImage = heroImageNames[indexPath.row]
performSegue(withIdentifier: "toDetailsVC", sender: nil)
}
Prepare for Segue
Implement the prepare(for:sender:) method to pass the selected data to the DetailsViewController before the transition happens.
// In ViewController.swift
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toDetailsVC" {
if let destinationVC = segue.destination as? DetailsViewController {
destinationVC.selectedHeroName = selectedName
destinationVC.selectedHeroImageName = selectedImage
}
}
}
Now, when you run the app, tapping a hero's name in the list will take you to the detail screen, which will display the correct name and image.
Note:
Using prepare(for:sender:) is the standard way to pass data between ViewControllers when using Storyboard segues. This keeps your code clean and organized.