Selecting only one location in the Location screen

You want the user to only select one location, and if another is selected, the location selected earlier should be deselected. Let's modify LocationDataManager to do this now. Perform the following steps:

  1. Click LocationDataManager.swift. Implement this method before the closing curly brace:
func findLocation (by name: String) -> (isFound:Bool, position:Int) {
guard let index = locations.firstIndex ( where: { $0.city == name} )
else {
return (isFound:false, position:0)
}
return (isFound: true, position: index)
}

This method takes a city name as a parameter. It then searches the locations array for a matching city, and if found, returns true and the index where that array item is stored as a single value. Such values are called tuples, and you can access each component of a tuple using its label (isFound and position, respectively).

  1. Click LocationViewController.swift. Create the following method after the viewDidLoad() method:
func set(selected cell:UITableViewCell, at indexPath: IndexPath) {
if let city = selectedCity?.city {
let data = manager.findLocation(by: city)
if data.isFound {
if indexPath.row == data.position {
cell.accessoryType = .checkmark
}
else { cell.accessoryType = .none }
}
}
else {
cell.accessoryType = .none
}
}

Let's break this method down:

  • set(selected cell:UITableViewCell, at indexPath: IndexPath)
    This function takes cell, a table view cell, and the cell's index path as arguments.
  • if let city = selectedCity?.city {
    let data = manager.findLocation(by: city)
    This checks to see whether the selectedCity property is set. If it is, the findLocation(by:) method in LocationDataManager is called. If a city is found, the tuple that is returned will have isFound set to true and position set to the index of the city in the locations array.
  • if data.isFound {
    if indexPath.row == data.position {
    cell.accessoryType = .checkmark
    }
    else { cell.accessoryType = .none }
    }
    If isFound is true, the cell's row is compared with position. If they are the same, the checkmark for that row is set. Otherwise, the checkmark is not set.
  • else {
    cell.accessoryType = .none
    If no data is found, the checkmark is not set.
  1.  In the tableView(_:cellForRowAt:) method, call set(selected:at:) after the line that sets the text for the cell's textLabel property. The tableView(_:cellForRowAt:) method should look like this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) 
-> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:
"locationCell", for: indexPath) as UITableViewCell
cell.textLabel?.text = manager.locationItem(at:indexPath).full
set(selected: cell, at: indexPath)
return cell
}

This means set(selected:at:) will be called for each row in the table view, and the checkmark will only be set on the row containing the selected location.

Build and run your project. You should only be able to set one location now, and if you choose another location, the location you chose earlier will be deselected.

You'll fix the second issue in the next section so that, once a location is selected, it will be persistent when you go back to the Locations screen. You'll also work on passing location and cuisine information to RestaurantListViewController, so it can eventually display a list of restaurants at a particular location matching the cuisine selected by the user.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.17.140