2

I have had a look but cannot find a suitable answer. I have a tableview populated with the names of drugs. The drugs have been entered as they have been encountered from text into Xcode as shown below.

class MasterViewController: UITableViewController {

// MARK: - Properties
var detailViewController: DetailViewController? = nil
var drugs = [Drug]()
var filtereddrugs = [Drug]()
let searchController = UISearchController(searchResultsController: nil)

// MARK: - View Setup
override func viewDidLoad() {
    super.viewDidLoad()

    // Setup the Search Controller
    searchController.searchResultsUpdater = self
    searchController.searchBar.delegate = self
    definesPresentationContext = true
    searchController.dimsBackgroundDuringPresentation = false

    // Setup the Scope Bar
    searchController.searchBar.scopeButtonTitles = ["All", "Green", "Blue", "Amber", "Red", "Black"]
    tableView.tableHeaderView = searchController.searchBar

    drugs = [
        Drug(category:"Green", name:"Magnesium Trisilicate"),
        Drug(category:"Green", name:"Co-magaldrox (Mucogel)"),
        Drug(category:"Green", name: "Gastrocote"),
        Drug(category:"Green", name:"Infant Gaviscon"),
        Drug(category:"Green", name:"Peptac"),
        Drug(category:"Green", name:"Mebeverine"),
        Drug(category:"Green", name:"Fybogel Mebeverine"),
        Drug(category:"Black", name:"Peppermint oil")]


 if let splitViewController = splitViewController {
            let controllers = splitViewController.viewControllers
            detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
        }
    }

override func viewWillAppear(_ animated: Bool) {
    clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
    super.viewWillAppear(animated)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

// MARK: - Table View
override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if searchController.isActive && searchController.searchBar.text != "" {
        return filtereddrugs.count
    }
    return drugs.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    let drug: Drug
    if searchController.isActive && searchController.searchBar.text != "" {
        drug = filtereddrugs[(indexPath as NSIndexPath).row]
    } else {
        drug = drugs[(indexPath as NSIndexPath).row]
    }
    cell.textLabel!.text = drug.name
    cell.detailTextLabel!.text = drug.category
    return cell
}

func filterContentForSearchText(_ searchText: String, scope: String = "All") {
    filtereddrugs = drugs.filter({( drug : Drug) -> Bool in
        let categoryMatch = (scope == "All") || (drug.category == scope)
        return categoryMatch && drug.name.lowercased().contains(searchText.lowercased())
    })
    tableView.reloadData()
}

// MARK: - Segues
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showDetail" {
        if let indexPath = tableView.indexPathForSelectedRow {
            let drug: Drug
            if searchController.isActive && searchController.searchBar.text != "" {
                drug = filtereddrugs[(indexPath as NSIndexPath).row]
            } else {
                drug = drugs[(indexPath as NSIndexPath).row]
            }
            let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
            controller.detailDrug = drug
            controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
            controller.navigationItem.leftItemsSupplementBackButton = true
        }
    }
}

}

extension MasterViewController: UISearchBarDelegate {
    // MARK: - UISearchBar Delegate
    func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
        filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
    }
}


extension MasterViewController: UISearchResultsUpdating {
    // MARK: - UISearchResultsUpdating Delegate
    func updateSearchResults(for searchController: UISearchController) {
        let searchBar = searchController.searchBar
        let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
        filterContentForSearchText(searchController.searchBar.text!, scope: scope)
    }
}

This list of drugs is not the full list, in fact in contains many many more, too many to sort manually! And over the next few weeks I will be entering more.

I don't have the time or will power to change it to appear in the table view in alphabetical order and I am wondering could a few lines of code solve the issue?

Cheers in advance,

Mark

Markc
  • 35
  • 1
  • 7
  • Do not put all of your drug data in code. Bad, bad idea. Put it all in a plist or a database and read in the data as runtime. – rmaddy Oct 05 '16 at 21:06
  • I have thought about doing it from a database but at the moment I am going to stay away from that and keep it in code for the time being. Cheers for the input though – Markc Oct 05 '16 at 21:19

1 Answers1

8

Try adding this, it will sort drugs whenever the property is set.

var drugs = [Drug]() {
    didSet {
        drugs.sort { $0.name < $1.name }
    }
}
Callam
  • 11,409
  • 2
  • 34
  • 32