Search code examples
iosswiftxcodeuikit

How do I present multiple alert controllers in a for loop in swift


I am having issues with presenting multiple alert controllers one after another. Want I want to do is have my for loop wait until the user dismisses the response controller. My code for presenting a message is below.

for block in blocks {
     self.presentMessage(title: codeBlock.stringInput1, message: codeBlock.stringInput2)
}
func presentMessage(title: String, message: String, completion: @escaping (Bool)->()) {
     let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)

     alert.addAction(UIAlertAction(title: "Done", style: .default, handler: { action in
          completion(true)
     }))

     self.present(alert, animated: true)
}

Edit --

This is my block class

class block: Codable {
    var type: String
    var stringInput1: String
    var stringInput2: String

    init(t: String, i1: String, i2: String) {
        type = t
        stringInput1 = i1
        stringInput2 = i2
    }
}

I have tried to use dispatch groups already but I was unsuccessful at getting it to correctly work. The end goal for my setup is to have the blocks be able to execute different actions depending on the type of the block. If it is possible I would like to make my for loops wait for the completion of a function until it continues.


Solution

  • Swift only lets you present one view controller at a time, so you'd have to do something like this:

    var blocks: [Block] = [Block.init(one: "1", two: "12"),
                            Block.init(one: "2", two: "22"),
                            Block.init(one: "3", two: "32")]
    
    func nextMessage(index: Int) {
        if index < blocks.count {
            let codeBlock = blocks[index]
            self.presentMessage(index: index, title: codeBlock.stringInput1, message: codeBlock.stringInput2)
        }
    }
    func presentMessage(index: Int, title: String, message: String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
    
        alert.addAction(UIAlertAction(title: "Done", style: .default, handler: { action in
            self.nextMessage(index: index + 1)
        }))
    
         self.present(alert, animated: true)
    }
    

    Calling presentMessage from the first item in the array will start it:

    self.presentMessage(index: 0, title: blocks[0].stringInput1, message: blocks[0].stringInput2)
    

    This is the quick and dirty Block class I created, but posting any related code like this in the future would be helpful for those answering questions.

    class Block {
        var stringInput1: String
        var stringInput2: String
    
        init(one: String, two: String) {
            stringInput1 = one
            stringInput2 = two
        }
    }