13

I'm trying to make an Alert Controller in which, if the Answer is "Ok", then it will perform a segue to a MapView. Here's the full code:

@IBAction func teste(_ sender: Any) {

    // Create the alert controller
    let alertController = UIAlertController(title: "Reservar vaga?", message: "Uma vaga será reservada em Estapar Estacionamento.", preferredStyle: .alert)

    // Create the actions
    let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {(alert:UIAlertAction) -> Void in

        let confirmAction = UIAlertController(title: "Vaga confirmada", message: "Gostaria de ter direções ao local?", preferredStyle: .alert)

        let okConfirmAction = UIAlertAction(title:"Sim", style: UIAlertActionStyle.default, handler:{(alert:UIAlertAction) -> Void in

            presentViewController(ViewController, animated: true, completion: nil)
        })

        let noConfirmAction = UIAlertAction(title:"Não", style: UIAlertActionStyle.default) {
            UIAlertAction in
            NSLog("Ok Pressed")
        }

        confirmAction.addAction(okConfirmAction)
        confirmAction.addAction(noConfirmAction)
        self.present(confirmAction, animated: true, completion: nil)
    })
    let cancelAction = UIAlertAction(title: "Cancelar", style: UIAlertActionStyle.cancel) {
        UIAlertAction in
        NSLog("Cancel Pressed")
    }

    // Add the actions
    alertController.addAction(okAction)
    alertController.addAction(cancelAction)

    //Append the button to the view
    self.present(alertController, animated: true, completion: nil)
}

I'm having trouble in this part:

let okConfirmAction = UIAlertAction(title:"Sim", style: UIAlertActionStyle.default, handler:{(alert:UIAlertAction) -> Void in

    presentViewController(ViewController, animated: true, completion: nil)
})

When i try to use presentViewController, this error appears: "Cannot convert value of type "ViewController.Type" to expected argument type 'UIViewController'"

And when I try to use performSegue, I use is this way:

performSegue(withIdentifier: "teste", sender: (Any).self)

And then the following error appears: "Implitcit use of self in closure; use 'self.' to make capture semantics explicit"

Can anyone please help me?

Pranav Kasetti
  • 8,770
  • 2
  • 50
  • 71
Lucas Leal
  • 245
  • 1
  • 2
  • 8
  • I assume that ViewController is class name, not class instance - hence the problem – Miknash Jul 26 '17 at 15:42
  • @Miknash can you please explain a little more? I'm new to swift :p – Lucas Leal Jul 26 '17 at 16:07
  • Do you have class ViewController? or do you have var ViewController: MyViewController? – Miknash Jul 26 '17 at 16:08
  • I have two viewControllers, the first one named ViewController (linked to the map view I want to show after the segue) and the second one named ViewController2 (linked to the initial view of the app) – Lucas Leal Jul 26 '17 at 17:19

2 Answers2

16

So to fix the presentViewController(ViewController, animated: true, completion: nil) function in the okConfirmAction closure, try this:

self?.present(ViewController(), animated: true, completion: nil)

And for the performSegue(withIdentifier:sender:) function in the okConfirmAction closure, try:

self?.performSegue(withIdentifier: "teste", sender: self)

As it is a closure you have to use self before calling the function. This is to make you aware that you may cause a retain cycle.

Write the closure as follows to prevent the retain cycle (using a weak self reference means we replace self with self? as a prefix for present(_:animated:completion:) and performSegue(withIdentifier:sender:)):

let okConfirmAction = UIAlertAction(title:"Sim", style: UIAlertActionStyle.default, handler:{ [weak self] (alert:UIAlertAction) -> Void in
//insert code from above
})
Pranav Kasetti
  • 8,770
  • 2
  • 50
  • 71
0

Use performSegue(withIdentifier: "teste", sender: self). I'm not sure what you're trying to achieve with the (Any). before self, since self on a class name returns the type of the class, not an instance of the class.

NRitH
  • 13,441
  • 4
  • 41
  • 44
  • I use (Any). before self because the console told me to do this, honestly (kinda new to the language)... when I use self only, it responds me "Implicit use of 'self' in closure; use 'self.' to make capture semantics explicit". – Lucas Leal Jul 26 '17 at 16:06
  • Ah. That happens only when you're in a block, and you usually just have to prefix your variables with `self?.`. – NRitH Jul 26 '17 at 16:07