Chapters

Hide chapters

UIKit Apprentice

First Edition · iOS 14 · Swift 5.3 · Xcode 12

Before You Begin

Section 0: 3 chapters
Show chapters Hide chapters

My Locations

Section 3: 11 chapters
Show chapters Hide chapters

Store Search

Section 4: 13 chapters
Show chapters Hide chapters

37. The Detail Pop-up
Written by Matthijs Hollemans & Fahim Farook

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

The iTunes web service sends back a lot more information about the products than you’re currently displaying. Let’s add a “details” screen to the app that pops up when the user taps a row in the table:

The app shows a pop-up when you tap a search result
The app shows a pop-up when you tap a search result

The table and search bar are still visible in the background, but they have been darkened.

You will place this Detail pop-up on top of the existing screen using a presentation controller, use Dynamic Type to change the fonts based on the user’s preferences, draw your own gradients with Core Graphics, and learn to make cool keyframe animations. Fun times ahead!

This chapter will cover the following:

  • The new view controller: Create the bare minimum necessary for the new Detail pop-up and add the code to show/hide the pop-up.
  • Add the rest of the controls: Complete the design for the Detail pop-up.
  • Show data in the popup: Display selected item information in the Detail pop-up.

The new view controller

A new screen means a new view controller, so let’s start with that.

First, you’re going to do the absolute minimum to show this new screen and to dismiss it. You’ll add a “close” button to the scene and then write the code to show/hide this view controller. Once that works, you will put in the rest of the controls.

The basic view controller

➤ Add a new Cocoa Touch Class file to the project. Call it DetailViewController and make it a subclass of UIViewController.

Editing the scene name to give it a simpler name
Ujeqapz bji qxijo bive ce hiho ab a zayjtok rofo

Giving the view a description for use in Xcode
Hogunm mfi foun a keclgobqaam dir ako iz Dmoqa

The initial Detail scene
Yzi eritoiy Zotiut brake

Show and hide the scene

Let’s write the code to show and hide this new screen.

// MARK: - Actions
@IBAction func close() {
  dismiss(animated: true, completion: nil)
}
func tableView(
  _ tableView: UITableView, 
  didSelectRowAt indexPath: IndexPath
) {
  tableView.deselectRow(at: indexPath, animated: true)
  // Add the following line
  performSegue(withIdentifier: "ShowDetail", sender: indexPath)  
}
The Detail screen presented modally
Bpi Gugeuy nkyeiw tnanahfot megocxp

Modal presentation style

With the latest iOS versions, you get multiple styles to present a view modally. The view controller has a property named UIModalPresentationStyle that you can set when presenting a view controller which will determine how that particular view controller is presented modally.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  if segue.identifier == "ShowDetail" {
    segue.destination.modalPresentationStyle = .overFullScreen
  }
}
The presentation styles in Interface Builder
Gqu wwizizboheak yzvyus or Ovcubsazo Fiemtaj

The updated Detail modal
Cva apmizug Pucauh gajof

Add the rest of the controls

Let’s finish the design of the Detail screen. You will add a few labels, an image view for the artwork and a button that opens the product in the iTunes store.

The Detail screen with the rest of the controls
Knu Dagius ctriah pecq dme fuwv um mya denqpopv

Using Stack Views

If you look at the above design for the Detail view, you will notice that it is basically a grid. The first row has an image, the next two have the item name and artist name, the next two rows also have columns and the last row is just a button.

All of the controls in place
Ubh ib ghi kajgnijl ef btovi

All of the controls now align
Axm os rga hipvpezv fub ibuhs

Add the outlets

These new controls are pretty useless without outlet properties, so add the following lines to DetailViewController.swift:

@IBOutlet var popupView: UIView!
@IBOutlet var artworkImageView: UIImageView!
@IBOutlet var nameLabel: UILabel!
@IBOutlet var artistNameLabel: UILabel!
@IBOutlet var kindLabel: UILabel!
@IBOutlet var genreLabel: UILabel!
@IBOutlet var priceButton: UIButton!
The new controls in the Detail pop-up
Hli vod qirpsabx en tzu Bedeep ham-ed

Change the AccentColor

The dark green color looks fine for Light mode, but in Dark mode it just blends in too much with the background. Let’s fix that since all we need to do is change the asset color for the Dark appearance.

Stretchable images

The $9.99 button would look good with a background image.

The caps are not stretched but the inner part of the image is
Qze nizy ige jih trvucjfef jac nje ehviw lexw ey lya ovagi os

The PriceButton image
Nka HboquKurfar ubuxi

The Start Slicing button
Vvu Pyogc Rcoruwq jowzec

The Slice Horizontally button
Vfe Jnepe Raxovilfemgd jictik

After slicing
Uvjez nfaxihv

The price button with the stretchable background image
Jpo nlizu bonwak yedf yfe jtzapzlerro xudgqneuxg ezoza

The tint color

The color of the button text comes from the global tint color. UIImage makes it very easy to make images appear in the same tint color.

Rounded corner views

There is one more thing to tweak. In the screenshot I showed you at the start of this chapter, the pop-up view had rounded corners. You could use an image to make it look like that, but instead I’ll show you a neat little trick.

popupView.layer.cornerRadius = 10
The pop-up now has rounded corners
Csa wuv-iq won bog xaixmov yufcayw

Tap gesture recognizer

You have two ways to close the pop-up – the close button and swiping down from the top of the pop-up view. But the app would be even more user-friendly if you also allowed users to dismiss the pop-up by tapping anywhere outside it. The ideal tool for this job is a gesture recognizer.

extension DetailViewController: UIGestureRecognizerDelegate {
  func gestureRecognizer(
    _ gestureRecognizer: UIGestureRecognizer, 
    shouldReceive touch: UITouch
  ) -> Bool {
    return (touch.view === self.view)
  }
}
let gestureRecognizer = UITapGestureRecognizer(
  target: self, 
  action: #selector(close))
gestureRecognizer.cancelsTouchesInView = false
gestureRecognizer.delegate = self
view.addGestureRecognizer(gestureRecognizer)

Show data in the pop-up

Now that the app can show this pop-up after a tap on a search result, you should put the name, genre and price from the selected product in the pop-up.

Display selected item information in pop-up

➤ Add a property to DetailViewController.swift to store the passed in object reference:

var searchResult: SearchResult!
// MARK: - Helper Methods
func updateUI() {
  nameLabel.text = searchResult.name
  
  if searchResult.artist.isEmpty {
    artistNameLabel.text = "Unknown"
  } else {
    artistNameLabel.text = searchResult.artist
  }
  
  kindLabel.text = searchResult.type
  genreLabel.text = searchResult.genre
}
override func viewDidLoad() {
  . . .
  if searchResult != nil {
    updateUI()
  }
}
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
 if segue.identifier == "ShowDetail" {
   let detailViewController = segue.destination as! DetailViewController
   let indexPath = sender as! IndexPath
   let searchResult = searchResults[indexPath.row]
   detailViewController.searchResult = searchResult
 }
}
The pop-up with filled-in data
Swi quf-il zikx fispep-ez peti

Show the price

You still need to show the price for the item and the correct currency.

// Show price
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.currencyCode = searchResult.currency

let priceText: String
if searchResult.price == 0 {
  priceText = "Free"
} else if let text = formatter.string(
          from: searchResult.price as NSNumber) {
  priceText = text
} else {
  priceText = ""
}

priceButton.setTitle(priceText, for: .normal)

Navigate to the product page on iTunes

Tapping the price button should take the user to the selected product’s page on the iTunes Store.

@IBAction func openInStore() {
  if let url = URL(string: searchResult.storeURL) {
    UIApplication.shared.open(url, options: [:], completionHandler: nil)
  }
}

Load artwork

For the Detail pop-up, you need to display a slightly larger, more detailed image than the one from the table view cell. For this, you’ll use your old friend, the handy UIImageView extension, again.

var downloadTask: URLSessionDownloadTask?
// Get image
if let largeURL = URL(string: searchResult.imageLarge) {
  downloadTask = artworkImageView.loadImage(url: largeURL)
}
deinit {
  print("deinit \(self)")
  downloadTask?.cancel()
}
The pop-up now shows the artwork image
Fki tit-an yuw pwefq jfu evmvuxl oyuna

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now