Chapter 28: The Locations Tab :: Page 662 Setting NavItem Title

Set up the edit view controller

Book’s code for setting LocationDetailsViewController's navigationItem.title?

var locationToEdit: Location?
var descriptionText = ""

// MARK: - ViewController Life Cycle
override func viewDidLoad() {
  super.viewDidLoad()
  if let location = locationToEdit{
   title = "Edit Location"
  }

Placing it within LocationsViewController's prepare(for:sender:) also worked. My thought was that locationToEdit will never be nil if the user is able to segue.

// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  guard segue.identifier == "EditLocation" else { return }
  ...
  guard let indexPath = tableView.indexPath(for: sender as! UITableViewCell) else { return }
  let location = locations[indexPath.row]
  controller.locationToEdit = location
  controller.navigationItem.title = "Edit Item"  // <---- Here

Question Is this considered coupled code since LocationDetailsViewController depends on LocationsViewController to set it’s navigationItem.title? property?

Question Is there any merit/demerit to doing it this way?

EDIT

Answered my second question:
Just came back to program some more, and found on the very next page - didSet{} is used on the locationToEdit property to populate existing location data to edit. :+1: Really awesome!

var locationToEdit: Location? {
  didSet {
    if let location = locationToEdit {
      descriptionText = location.locationDescription
      categoryName = location.category
      date = location.date
      coordinate = CLLocationCoordinate2DMake(location.latitude, 
                                              location.longitude)
      placemark = location.placemark
    }
  }
}

This is off topic but rather than make new thread…

I learned to group my files within the Project Navigator like so:

Where would the Functions.swift file that holds the free funcs go? :open_file_folder: Supporting Files?
I leave the AppDelegate.swift file at the top, is there a better group to place it?.
All the files are in the :open_file_folder: MyLocations, these are created Groups.

Looking for advice for best practices from the pros.

Thanks!
Rebecca

I think you might be looking for the “correct” answer :slight_smile: Personally, I don’t believe in one “correct” way to do things. You can do whatever works best for you since my approach might not be the most intuitive one for you and vice versa. As long as the code works, does not create any resource issues, and does not pose any issues with regards to maintaining it (especially for somebody who might not be you), i say go with the approach that works for you.

That said, I personally try to have one-time update stuff for a view controller in the viewDidLoad for that view controller since that’s an easy place to find all the set up code. If you have the set up code for one view controller in another (by way of prepare(for:sender:)) then you might be making that information harder to find for somebody else who might have to maintain the code :slight_smile:

Sure, they can certainly do a bit of digging and find the relevant bits. But making the code easier to maintain would be a good thing is my opinion.

In the same vein of “do what works for you”, you should feel free to organize the code as you like too :smiley: I generally put something like Functions.swift under either Supporting Files (if that’s the only file which doesn’t go anywhere else) or under a special “Tools” or (“Helpers”) folder if there are other similar files.

Again, I’d say do what works for you - there are no hard and fast rules :slight_smile:

1 Like

I updated my post moments ago to reflect that I saw the use of didSet{}.
I’m rereading the text in the book and I realize that setting it from LocationsViewController prepare(for:sender:)
controller.locationToEdit = location
that is what invokes (correct terminology? or executes?) the didSet{}.
if let location = locationToEdit { title = "Edit Location" } is checking for nil, and won’t invoke the property observer didSet{} in locationToEdit.


Thank you for this info! And I agree it makes sense to have it together in one place.

Do you make helper methods to neaten the code and call them?
I look at the viewDidLoad() and am cringing at the 15 lines of code and wanting to consolidate them in other functions, and call them one by one from viewDidLoad().

For example:

override func viewDidLoad() {
  super.viewDidLoad()
  setUp()
  deactivateKeyboard()
}

func setUp() {
  if let location = locationToEdit {
    title = "Edit Location"
  }
  descriptionTextView.text = descriptionText
  ...
  dateLabel.text = format(date: date)
}

func deactivateKeyboard() {
  let gestureRecognizer = UITapGestureRecognizer(target: self,
                                                 action: #selector(hideKeyboard))
  gestureRecognizer.cancelsTouchesInView = false
  tableView.addGestureRecognizer(gestureRecognizer)
}

I like this! Thank you for sharing this info with me!

Cheers!
Rebecca

Again, a matter of personal preference as far as I’m concerned :slight_smile: I know that some people have this aversion to long methods and think that all methods should be compact and small. And I can understand the reasoning … sometimes :stuck_out_tongue:

My personal preference for creating new methods is to prevent code duplication - if the same functionality is used from multiple locations, make it a new method. Just creating new methods for the sake of cleaning out code is not something I do often … unless there is an additional reason for doing so. Instead, I separate out each functional part in a method using comments - that is enough of an organization - for me personally, that is.

1 Like

I actually recall reading this… DRY Don’t repeat yourself :smile:
Sorry for so many off topic questions, I am wanting to develop good coding habits :+1:
Thank you for taking the time to answer them!
Rebecca

No worries about the questions, if you have any feel free to ask :slight_smile: It’s always good to clear doubts and to have a good understanding of things.

1 Like

Another reason to keep the title-setting code in the view controller: you may find that you want to display the edit view from two or more places. (Spoiler alert: Maybe from the map view, for instance). You would have to remember to set it from each place, and make sure you set it the same way. Better to have it in one place.

The unofficial “official” folder for stuff like Functions.swift is “Utilities”. :slight_smile:

1 Like

This topic was automatically closed after 166 days. New replies are no longer allowed.