ios – UITableView reordering controls aren’t appearing in UIViewController


Not sure what is wrong, I feel like I’ve done this a thousand times over the years, but its not working this time.

I have a UIViewController (not UITableViewController) and I create a UITableView in loadView(). I set the delegate and the datasource. I implement the canMoveRowAt and the moveRowAt delegate methods. I add a UIBarButtonItem to tap to put the table into edit mode but none of the reorder controls show up.

class MyTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var tableview: UITableView!

    override func loadView() {
        // intentionally not calling super
        
        self.tableview = UITableView(frame: .zero, style: .grouped)
        self.tableview.delegate = self
        self.tableview.dataSource = self
        self.view = self.tableview
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableview.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        
        let reorderbutton = UIBarButtonItem(image: UIImage(systemName: "mount"), style: .plain, target: self, action: #selector(tappedreorder(_:)))
        
        self.navigationItem.rightBarButtonItems = [reorderbutton]
    }
        
    @objc func tappedreorder(_ sender:Any) {
        self.tableview.setEditing(true, animated: true)
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        var config = cell.defaultContentConfiguration()
        config.text = ...
        cell.contentConfiguration = config
        
        return cell
    }
    

    func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        print("moved row from \(sourceIndexPath) to \(destinationIndexPath)")
    }
    
    func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        print("can move row at \(indexPath), true")
        return true
    }
    
}

When I set the table into editing mode, I don’t get any calls backs to canMoveRowAt and none of the rows show the reorder controls.

I’ve also tried adding cell.showsReorderControl = self.tableview.isEditing to the cellForRowAt implementation so that it explicitly requests the move control, but that didn’t change anything because none of the rows were actually being reloaded. Even when I set the table into edit mode and then did a reloadData() to reload all the rows and set cell.showsReorderControl, they still didn’t show up.

Leave a Reply

Your email address will not be published. Required fields are marked *