Search code examples
iosxcodeswiftuialertcontrolleruitableviewrowaction

UITableViewRowAction and UIAlertController


I have created UITableView with UITableViewRowAction: edit and delete. When pressing the delete, confirmation should appear as UIAlertController. If user press delete, cell should be deleted, and if user press cancel, cell should be deleted and UIAlertController should disappear. I wrote this code, but it does not work as intended.

let edit = UITableViewRowAction(style: .normal, title: "Изменить") { action, index in
        self.performSegue(withIdentifier: "LEDChangesSegue", sender: self.tableView.cellForRow(at: indexPath))
    }
    edit.backgroundColor = UIColor.init(red: 0, green: 122.0/256.0, blue: 1, alpha: 1)

    let delete = UITableViewRowAction(style: .normal, title: "Удалить") { action, index in

        let alertController = UIAlertController(title: self.ledControllers[indexPath.row].name, message: "Действительно удалить этот контроллер?", preferredStyle: .alert)
        var answer = true

        let cancelAction = UIAlertAction(title: "Отмена", style: .cancel) { (action:UIAlertAction!) in answer = false
        }

        let deleteAction = UIAlertAction(title: "Удалить", style: .destructive ) { (action:UIAlertAction!) in answer = true
        }
        alertController.addAction(deleteAction)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)

        if  answer {
            self.ledControllers.remove(at: index.row)
            saveLED(self.ledControllers)
            self.tableView.deleteRows(at: [index], with: .fade)
        }}
    delete.backgroundColor = UIColor.red()

    return [edit, delete]

always returns the original value var answer = true , not what I click in UIAlertController. What fix the code to make it work correctly?


Solution

  • Solution 1

    You can do that directly without taking the variable answer because this is local variable and has no scope outside of this block

    let edit = UITableViewRowAction(style: .normal, title: "Изменить") { action, index in
        self.performSegue(withIdentifier: "LEDChangesSegue", sender: self.tableView.cellForRow(at: indexPath))
    }
    edit.backgroundColor = UIColor.init(red: 0, green: 122.0/256.0, blue: 1, alpha: 1)
    
    let delete = UITableViewRowAction(style: .normal, title: "Удалить") { action, index in
    
        let alertController = UIAlertController(title: self.ledControllers[indexPath.row].name, message: "Действительно удалить этот контроллер?", preferredStyle: .alert)
    
        let cancelAction = UIAlertAction(title: "Отмена", style: .cancel) { (action:UIAlertAction!) in
        }
    
        let deleteAction = UIAlertAction(title: "Удалить", style: .destructive ) { (action:UIAlertAction!) in 
            self.ledControllers.remove(at: index.row)
            self.saveLED(self.ledControllers)
            self.tableView.deleteRows(at: [index], with: .fade)
        }
        alertController.addAction(deleteAction)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)
    
    delete.backgroundColor = UIColor.red()
    
    return [edit, delete]
    

    Solution 2

    If you really want to do this with the variable answer(which actually has no meaning to use), write a separate function to delete the row.

    func deleteRowNow(answer : Bool, forRow : NSIndexPath)
    {
        if  answer {
            self.ledControllers.remove(at: index.row)
            saveLED(self.ledControllers)
            self.tableView.deleteRows(at: [index], with: .fade)
        }}
    }
    

    and call it from your call inside the block of UIAlertAction

    let edit = UITableViewRowAction(style: .normal, title: "Изменить") { action, index in
        self.performSegue(withIdentifier: "LEDChangesSegue", sender: self.tableView.cellForRow(at: indexPath))
    }
    edit.backgroundColor = UIColor.init(red: 0, green: 122.0/256.0, blue: 1, alpha: 1)
    
    let delete = UITableViewRowAction(style: .normal, title: "Удалить") { action, index in
    
        let alertController = UIAlertController(title: self.ledControllers[indexPath.row].name, message: "Действительно удалить этот контроллер?", preferredStyle: .alert)
        var answer = true
    
        let cancelAction = UIAlertAction(title: "Отмена", style: .cancel) { (action:UIAlertAction!) in 
              answer = false
              self.deleteRowNow(answer, forRow : index)
        }
    
        let deleteAction = UIAlertAction(title: "Удалить", style: .destructive ) { (action:UIAlertAction!) in 
              answer = true
              self.deleteRowNow(answer, forRow : index)
        }
        alertController.addAction(deleteAction)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)
    
    delete.backgroundColor = UIColor.red()
    
    return [edit, delete]