Nested UiAlerts - Show alert in UIAlert Action

30 Views Asked by At

I would like to present a second UIAlertController in UIAlertAction. The second UIAlertController is called by method 'deletePoints'. The problem is that the first action does not wait for the second action. It seems that the first UIAction is called twice when the second action is finished. How can I solve the problem? I have to wait for 'deletePoints'. Any ideas?

Thank you in advance.

        alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { [self] (action: UIAlertAction!) in
            for (index, indexPath) in selectedIndexPaths.enumerated() {

             // some code...
                
                if table[0].points >= 100 {
                    deletePoints(table: table)
                }
                
                // add points,
                if position?.category == 0 {
                    if table[0].segment == 3 {
                        table[0].points += 5
                        self.tablesService?.update(updatedTable: table[0])
                    }
                }
             
             // some code...

         self.present(alertController, animated: true, completion: nil)
func deletePoints(table: [Tables]) {
        let pointsAlertController = UIAlertController(title: "Some text", message:
            "Delete points?", preferredStyle: .alert)
        pointsAlertController.addAction(UIAlertAction(title: "Nein", style: .cancel, handler: nil))
        
        pointsAlertController.addAction(UIAlertAction(title: "Ja", style: .default, handler: { [self] (action: UIAlertAction!) in
            table[0].points -= 100
            self.tablesService?.update(updatedTable: table[0])
        }))

        self.present(pointsAlertController, animated: true)
}
1

There are 1 best solutions below

0
HangarRash On

The easiest is to refactor your code so the final deletion code is in a separate function. Then you can call it as needed.

All of the code inside the "OK" alert action that you were calling after the call to deletePoints needs to go a new method:

function finishDeletePoints(table: [Table]) {
    // add points,
    if position?.category == 0 {
        if table[0].segment == 3 {
            table[0].points += 5
            self.tablesService?.update(updatedTable: table[0])
        }
    }

    // some code...
}

That might need another parameter or two depending on the scope of some other variables.

Then the "OK" handler becomes:

alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { [self] (action: UIAlertAction!) in
    for (index, indexPath) in selectedIndexPaths.enumerated() {
        // some code...
    }
        
    if table[0].points >= 100 {
        deletePoints(table: table)
    } else {
        finishDeletePoints(table: table)
    }
}

I'm guessing at some of this since you haven't show all of the code. But the idea is to either call deletePoints to get the 2nd alert, or to call finishDeletePoints for the rest of the code.

And lastly, you update deletePoints to call finishDeletePoints based on the user's choice in the 2nd alert.

func deletePoints(table: [Tables]) {
    let pointsAlertController = UIAlertController(title: "Some text", message:
        "Delete points?", preferredStyle: .alert)
    pointsAlertController.addAction(UIAlertAction(title: "Nein", style: .cancel, handler: nil))
    
    pointsAlertController.addAction(UIAlertAction(title: "Ja", style: .default, handler: { [self] (action: UIAlertAction!) in
        table[0].points -= 100
        self.tablesService?.update(updatedTable: table[0])
        finishDeletePoints(table) // Add this line
    }))

    self.present(pointsAlertController, animated: true)
}

Again, I'm guessing a bit on your required logic but you should get the general idea on this refactoring.