114

I'm presenting a UIAlertView to the user and I can't figure out how to write the handler. This is my attempt:

let alert = UIAlertController(title: "Title",
                            message: "Message",
                     preferredStyle: UIAlertControllerStyle.Alert)

alert.addAction(UIAlertAction(title: "Okay",
                              style: UIAlertActionStyle.Default,
                            handler: {self in println("Foo")})

I get a bunch of issues in Xcode.

The documentation says convenience init(title title: String!, style style: UIAlertActionStyle, handler handler: ((UIAlertAction!) -> Void)!)

The whole blocks/closures is a little over my head at the moment. Any suggestion are much appreciated.

Steve Marshall
  • 7,919
  • 4
  • 16
  • 17

10 Answers10

173

Instead of self in your handler, put (alert: UIAlertAction!). This should make your code look like this

    alert.addAction(UIAlertAction(title: "Okay",
                          style: UIAlertActionStyle.Default,
                        handler: {(alert: UIAlertAction!) in println("Foo")}))

this is the proper way to define handlers in Swift.

As Brian pointed out below, there are also easier ways to define these handlers. Using his methods is discussed in the book, look at the section titled Closures

progrmr
  • 75,956
  • 16
  • 112
  • 147
Jacob
  • 2,769
  • 3
  • 21
  • 29
  • 9
    `{alert in println("Foo")}`, `{_ in println("Foo")}`, and `{println("Foo")}` should also work. – Brian Nickel Jun 12 '14 at 17:44
  • 8
    @BrianNickel: The 3rd one don't work because you need to handle the argument action. But in addition to that you don't have to write UIAlertActionStyle.Default in swift. .Default works, too. – Ben Jul 29 '14 at 17:26
  • Note that if you use a "let foo = UIAlertAction(...), then you can use the trailing closure syntax to put what might be a long closure after the UIAlertAction - it looks pretty nice that way. – David H Oct 01 '14 at 15:22
  • 1
    Here's an elegant way to write this: `alert.addAction(UIAlertAction(title: "Okay", style: .default) { _ in println("Foo") })` – Elijah Dec 03 '17 at 03:45
81

Functions are first-class objects in Swift. So if you don't want to use a closure, you can also just define a function with the appropriate signature and then pass it as the handler argument. Observe:

func someHandler(alert: UIAlertAction!) {
    // Do something...
}

alert.addAction(UIAlertAction(title: "Okay",
                              style: UIAlertActionStyle.Default,
                              handler: someHandler))
Rob Johansen
  • 5,076
  • 10
  • 40
  • 72
  • how should look this handler function in objective-C? – andilabs Aug 08 '15 at 15:46
  • 1
    Functions **are** closures in Swift :) which I though was pretty cool. Check out the docs: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html – kakubei Aug 24 '15 at 08:32
19

You can do it as simple as this using swift 2:

let alertController = UIAlertController(title: "iOScreator", message:
        "Hello, world!", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Destructive,handler: { action in
        self.pressed()
}))

func pressed()
{
    print("you pressed")
}

    **or**


let alertController = UIAlertController(title: "iOScreator", message:
        "Hello, world!", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Destructive,handler: { action in
      print("pressed")
 }))

All the answers above are correct i am just showing another way that can be done.

Korpel
  • 2,432
  • 20
  • 30
11

Lets assume that you want an UIAlertAction with main title, two actions (save and discard) and cancel button:

let actionSheetController = UIAlertController (title: "My Action Title", message: "", preferredStyle: UIAlertControllerStyle.ActionSheet)

    //Add Cancel-Action
    actionSheetController.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil))

    //Add Save-Action
    actionSheetController.addAction(UIAlertAction(title: "Save", style: UIAlertActionStyle.Default, handler: { (actionSheetController) -> Void in
        print("handle Save action...")
    }))

    //Add Discard-Action
    actionSheetController.addAction(UIAlertAction(title: "Discard", style: UIAlertActionStyle.Default, handler: { (actionSheetController) -> Void in
        print("handle Discard action ...")
    }))

    //present actionSheetController
    presentViewController(actionSheetController, animated: true, completion: nil)

This works for swift 2 (Xcode Version 7.0 beta 3)

polarware
  • 2,499
  • 1
  • 24
  • 18
9

In Swift 4 :

let alert=UIAlertController(title:"someAlert", message: "someMessage", preferredStyle:UIAlertControllerStyle.alert )

alert.addAction(UIAlertAction(title: "ok", style: UIAlertActionStyle.default, handler: {
        _ in print("FOO ")
}))

present(alert, animated: true, completion: nil)
7

Syntax change in swift 3.0

alert.addAction(UIAlertAction(title: "Okay",
                style: .default,
                handler: { _ in print("Foo") } ))
Fangming
  • 24,551
  • 6
  • 100
  • 90
4

this is how i do it with xcode 7.3.1

// create function
func sayhi(){
  print("hello")
}

// create the button

let sayinghi = UIAlertAction(title: "More", style: UIAlertActionStyle.Default, handler:  { action in
            self.sayhi()})

// adding the button to the alert control

myAlert.addAction(sayhi);

// the whole code, this code will add 2 buttons

  @IBAction func sayhi(sender: AnyObject) {
        let myAlert = UIAlertController(title: "Alert", message:"sup", preferredStyle: UIAlertControllerStyle.Alert);
        let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler:nil)

        let sayhi = UIAlertAction(title: "say hi", style: UIAlertActionStyle.Default, handler:  { action in
            self.sayhi()})

        // this action can add to more button
        myAlert.addAction(okAction);
        myAlert.addAction(sayhi);

        self.presentViewController(myAlert, animated: true, completion: nil)
    }

    func sayhi(){
        // move to tabbarcontroller
     print("hello")
    }
Alan
  • 329
  • 4
  • 10
4

create alert, tested in xcode 9

let alert = UIAlertController(title: "title", message: "message", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: self.finishAlert))
self.present(alert, animated: true, completion: nil)

and the function

func finishAlert(alert: UIAlertAction!)
{
}
luhuiya
  • 2,129
  • 21
  • 20
1
  1. In Swift

    let alertController = UIAlertController(title:"Title", message: "Message", preferredStyle:.alert)
    
    let Action = UIAlertAction.init(title: "Ok", style: .default) { (UIAlertAction) in
        // Write Your code Here
    }
    
    alertController.addAction(Action)
    self.present(alertController, animated: true, completion: nil)
    
  2. In Objective C

    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *OK = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action)
    {
    }];
    
    [alertController addAction:OK];
    
    [self presentViewController:alertController animated:YES completion:nil];
    
Jignesh Mayani
  • 6,937
  • 1
  • 20
  • 36
0

In Swift 5, here's what you can also do:

let handler = { (action: UIAlertAction!) -> Void in
    //do tasks
}

Then when you are making the action, just substitute it in like this:

let action = UIAlertAction(title: "Do it", style: .default, handler: handler)
Alex Aghajanov
  • 294
  • 4
  • 17