Bronze Challenge Solution, Chapter 9

Changes are made only in these 2 files:
ItemsStore.swift :

import UIKit

class ItemStore {
    var allItems = [[Item](), [Item]()]
    
    @discardableResult func createItem() -> Item {
        let newItem = Item(random: true)
        newItem.valueInDollars <= 50 ? allItems[0].append(newItem) : allItems[1].append(newItem)
        return newItem
    }
    
    func removeItem(_ item: Item) {
        let section = item.valueInDollars <= 50 ? 0 : 1
        if let index = allItems[section].firstIndex(of: item) {
            allItems[section].remove(at: index)
        }
    }
    
    func moveItem(from fromIndex: IndexPath, to toIndex: IndexPath) {
        if fromIndex == toIndex {
            return
        }
        
        // Get reference to object being moved so you can reinsert it
        let movedItem = allItems[fromIndex.section][fromIndex.row]
        
        // Remove item from array
        allItems[fromIndex.section].remove(at: fromIndex.row)
        
        // Insert item in array at new location
        allItems[toIndex.section].insert(movedItem, at: toIndex.row)
    }
}

ItemsViewController.swift:

import UIKit

class ItemsViewController: UITableViewController {
    var itemsStore: ItemStore!
    
    @IBAction func addNewItem(_ sender: UIButton) {
        // Create a new item and add it to the store
        let newItem = itemsStore.createItem()
        
        // Figure out where the item is in the array
        let section = newItem.valueInDollars <= 50 ? 0 : 1
        if let index = itemsStore.allItems[section].firstIndex(of: newItem){
            let indexPath = IndexPath(row: index, section: section)
            
            // Insert this new row into the table
            tableView.insertRows(at: [indexPath], with: .automatic)
        }
    }
    
    @IBAction func toggleEditingMode(_ sender: UIButton){
        // If you are currently in editing mode...
        if isEditing {
            // Change text of button to inform user of state
            sender.setTitle("Edit", for: .normal)
            
            // Turn off editing mode
            setEditing(false, animated: true)
        } else {
            // Change text of button to inform user of state
            sender.setTitle("Done", for: .normal)
            
            // Enter editing mode
            setEditing(true, animated: true)
        }
    }
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return itemsStore.allItems[section].count
    }

    override func tableView(_ tableView: UITableView,
                            cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // Get a new or recycled cell
        let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)

        // Set the text on the cell with the description of item
        // that is at the nth index of item, where n = row this cell
        // will appear in on the table view
        let item = itemsStore.allItems[indexPath.section][indexPath.row]

        cell.textLabel?.text = item.name
        cell.detailTextLabel?.text = "$\(item.valueInDollars)"

        return cell
    }
    
    override func tableView(_ tableView: UITableView,
                            commit editingStyle: UITableViewCell.EditingStyle,
                            forRowAt indexPath: IndexPath) {
        // If the table view is asking to commit a delete command...
        if editingStyle == .delete {
            let item = itemsStore.allItems[indexPath.section][indexPath.row]
            
            // Remove the item from the store
            itemsStore.removeItem(item)
            
            // Also remove that roe from the table view with an animation
            tableView.deleteRows(at: [indexPath], with: .automatic)
        }
    }
    
    override func tableView(_ tableView: UITableView,
                            moveRowAt sourceIndexPath: IndexPath,
                            to destinationIndexPath: IndexPath) {
        // Update the model
        itemsStore.moveItem(from: sourceIndexPath, to: destinationIndexPath)
    }
    
    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        section == 0 ? "Items <= $50" : "Items > $50"
    }
}