Skip to content

Latest commit

 

History

History

day-017

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Day 17: Project 1, Part Two

Follow along at https://www.hackingwithswift.com/100/17.

📒 Field Notes

This day continues with the projects in Hacking with Swift.

I have a separate repository where I've been creating projects alongside the material in the book. And you can find Project 1 here. However, this day focused specifically on a number of topics:

  • Building a detail screen
  • Loading images with UIImage
  • Final tweaks: hidesBarsOnTap, safe area margins

Building a detail screen

Using storyboards and code together, the general flow for this includes creating a new file/class for our ViewController, adding a ViewController to the storyboard, and then syncing the two by selecting the ViewController's class in the storyboard Identity Inspector.

We can continue this process at a more granular level: creating elements in storyboard, and then wiring up outlet connections to our code.

As I've become more immersed in the Swift community, I've noticed how everyone seems to have differing opinions regarding the usages of storyboards vs keeping everything in code.

Personally, I'm on the side of "it depends" 🙂. I love finding ways that the two can be used together, and I think it's best to be mindful of which use cases benefit which domain.

Anyway, another important topic covered here was the way our DetailViewController declared its imageView outlet as an implicitly unwrapped optional:

class DetailViewController: UIViewController {
    @IBOutlet var imageView: UIImageView!

    ...
}

We do this because when the DetailViewController is first created, the imageView hasn't been created yet. At the same time, though, iOS needs to know how much memory to devote to the DetailViewController.

So — because we know that the imageView will exist by the time we want to use it — an implicitly unwrapped optional is a perfect way to make a declaration that satisfies both the operating system and our future needs.

Loading images with UIImage

This section covered a way to load a detail view with an image name after its image was selected out of a parent table view:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if let detailViewController = storyboard?.instantiateViewController(withIdentifier: "Image Detail") as? DetailViewController {
        detailViewController.imageName = imageNames[indexPath.row]
        navigationController?.pushViewController(detailViewController, animated: true)
    }
}

Our DetailViewController can then be set up to take the imageName it's handed and load a UIImage for its own imageView:

class DetailViewController: UIViewController {
    @IBOutlet var imageView: UIImageView!

    var imagePath: String?

    override func viewDidLoad() {
        super.viewDidLoad()

        if  imageName != nil {
            imageView.image = UIImage(named: imageName)
        }
    }
}

I'm curious about how standard this approach is. For computing a selected image and then setting it on a controller with a simple image view, it seems solid. But I'm wondering what patterns exist for transitioning between more complex views... in more complex view hierarchies... with much more dynamic data... without necessarily being coupled to the storyboard. Probably a bit out of our scope here. But I've heard good things about the Coordinator Pattern in iOS, and it's on my to-do list to explore in depth. For now, though, our storm viewing is operational ⚡️!

🔗 Related Links