• 20 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 3/6/20

Implement detail view

Log in or subscribe for free to enjoy all this course has to offer!

We’ve got our grid sorted out, and we’ve presented the most useful information for the user to scan.

The user may want to explore items in more detail to decide whether or not to follow through. For that, we’ll present a full-screen view of a selected item, using another view controller.

Implementing the detail view

Our detail view will consist of two parts:

  • The actual details about a selected item 

  • The related swag elements (at this moment we'll be emulating the relativity)

Choosing the layout

Let's explore the following options:

  • Plain view

  • Scroll view

  • Table view

  • Collection view

Plain view

This option is simple, and it's good to know that there will be very few elements that can always fit onto any device size.

The advantage, of course, is the minimal effort; the disadvantage is that there is no guarantee of a layout that fits should our content require more space.

Scroll view

Using the scroll view is similar to plain view; however, it solves the question of the content fitting.

It adds on some effort - we need to manage the scroll view content.

Table view

Table views are a very common and convenient way to display scrollable content. It's also useful for repeatable content that can be grouped in sections by creating cells with various layouts. On top of that, there's a convenient way to organize the headers and footers of each section as well as have a header and a footer for the whole table.

This component requires even more effort to implement; however, it provides undoubtable benefits.

Collection view

Adopting collection views presents an opportunity to use all the capabilities of table views with the addition of creating a grid environment that is scrollable in either direction.

For sophisticated components, the collection view would definitely be a winner. In our example, we have simple data to present, and at the moment our designs are open for adjustments. Therefore, we'll use the simplest option - plain view! ☺️

Go ahead and position the necessary elements to compose the detail view:

  • Media item:

    • UIImageView for the artwork

    • Three UILabel objects for the title, artist name, and collection name

    • A UIButton to offer an option to switch to iTunes

  • Swag item:

    • UIView to serve as a container for the swag related elements

    • UIImageView for the artwork

    • UILabel for the title

In the end, it will look like this:

Detail view
Detail view

We're placing the swag related elements on a separate view so that they all stay together. We'll see the utility of it shortly: 😉

Swag view on media detail view
Swag view on media detail view

Populating the data

Here we need to display the actual data. It will depend on the user's selection on the list view. For that, we need to implement the following:

  • Display the details of a selected media object.

  • Provide an option to reach out to iTunes through an iTunes button tap.

  • Provide an option to reach out to a swag source through a swag view tap.

Let's start with displaying media object details.

How do we know which item was selected? 🤔

We'll use a single detail view controller object for any media item the user selects. In order to know which one has been selected, we must pass some parameter to the view controller.

Passing parameters

At this point, the most efficient parameter to pass will be the mediaId - it will allow us to communicate with iTunes API to get more details. So, let's add a property for that:

var mediaId: Int!

We'll also need a couple more variables:

  • to hold the full media object; 

  • to hold a 'related' swag.

We can declare variables to accomplish just that:

private var swag: Swag?
private var media: Media?

We are going to set the variables internally, so it's better to keep them private. They are also optional as there's a chance we won't be able to get them - due to network connection or API malfunction. 😣

Redirecting to Safari

Next, we need to implement a method that will allow us to open a URL in the Safari app. And - if something goes wrong - communicate it to the user. For this, we'll implement two helper methods:

  • openURL  - this method will take a URL string as a parameter, check its value, and attempt to convert it to a URL. If something goes wrong, it will display an alert communicating the matter to the user.

  •  presentNoDataAlert  - this method will display an acknowledgment alert, taking the title and message as parameters.

Here's the code:

func openURL(sourceUrl: String?) {
if let sourceUrl = sourceUrl, let url = URL(string: sourceUrl) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
else {
self.presentNoDataAlert(title: "Oops, something happened...",
message: "Can't take you to the source")
}
}
func presentNoDataAlert(title: String?, message: String?) {
let alertController = UIAlertController(title: title,
message: message,
preferredStyle: .alert)
let dismissAction = UIAlertAction(title: "Got it", style: .cancel, handler: { (action) -> Void in
})
alertController.addAction(dismissAction)
present(alertController, animated: true)
}

Notice that we use  UIApplication.shared  while requesting to open Safari.

Does this look familiar?

We are using static property  shared  of the  UIApplication  class and it's a singleton! It makes sense - there's only one object per application. 😎 Needless to say,  UIApplication  object represents the whole application!

Great! Now, let's link this useful code to the UI!

Connecting to iTunes

Connecting to iTunes is straightforward - when the user taps the More on iTunes button, we can process the transition. Let's create an action method:

@IBAction func storeButtonTapped(_ sender: Any) {
openURL(sourceUrl: media?.sourceUrl)
}

We are simply calling our helper method and passing it an optional URL string from the media object.

Now, let's connect the button to the code by creating an action in the storyboard:

Creating a button action
Creating an action button  
Connecting to swag reference

Next we need to reference a swag resource. This is similar to the iTunes connection - we simply provide a URL from the swag object:

@IBAction func swagTapped(_ sender: Any) {
openURL(sourceUrl: swag?.sourceUrl)
}

We don't have a button to connect it to! So instead, we are going to add a tap gesture recognizer to our view controller, assign it to the swag view container, and connect the action for the gesture to the method we just created. Let's do this! 💪

Add a gesture recognizer object to the swag view in the storyboard by dragging it from the Object Library onto the swag view container.

Add gesture recognizer to swag view container
Add gesture recognizer to swag view container

Connect the gesture recognizer to the action method:

Create action for tap gesture
Create action for tap gesture

Great job! 😁

It would be nice to see this in action, but we can't access that view for the moment.

Not for now, at least! We'll make the necessary connection and implement transitions in the next chapter! 😉

Let's recap!

  • Providing detail view for list items is a common technique to present extensive information for list items.

  • Common layout presentations for various content are:

    • Plain view

    • Scroll view

    • Table view

    • Collection view

  • UIApplication  object represents the whole application and provides static  shared  property that implements the singleton code design pattern.

Example of certificate of achievement
Example of certificate of achievement