The code is pretty straightforward the only thing needing to be refactored is the section titles titleForHeaderInSection
. I’m not happy with them being coded in the controller. I would prefer to have the title and data coupled, but that would call for a dictionary and tableView’s protocol functions pass in Ints and they don’t play well with dictionaries.
itemStore.swift
class ItemStore {
var allItems = [Item]()
@discardableResult func createItem() -> Item {
let newItem = Item(random: true)
allItems.append(newItem)
return newItem
}
func filterItemsBy(_ price: Int = 50) -> [[Item]] {
var filteredItems = [[Item](), [Item]()]
for item in allItems {
if item.valueInDollars > price {
filteredItems[0].append(item)
} else {
filteredItems[1].append(item)
}
}
return filteredItems
}
init() {
for _ in 0..<5 {
createItem()
}
}
}
itemsViewController.swift
class ItemsViewController: UITableViewController {
var filteredItems = [[Item]]()
var itemStore: ItemStore! {
didSet {
// reload table each time new data is set
filteredItems = itemStore.filterItemsBy()
self.tableView.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
let statusBarHeight = UIApplication.shared.statusBarFrame.height
let insets = UIEdgeInsets(top: statusBarHeight, left: 0, bottom: 0, right: 0)
tableView.contentInset = insets
tableView.scrollIndicatorInsets = insets
}
override func numberOfSections(in tableView: UITableView) -> Int {
return filteredItems.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 0:
return "Over $50"
case 1:
return "Under $50"
default:
return nil
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredItems[section].count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = filteredItems[indexPath.section][indexPath.row]
// this is better for memory management but must be configued in IB
let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)
cell.textLabel?.text = item.name
cell.detailTextLabel?.text = "$\(item.valueInDollars)"
return cell
}
}