18

I have the following alert method.

static func notifyUser(_ title: String, message: String) -> Void
{
    let alert = UIAlertController(title: title,
                                  message: message,
                                  preferredStyle: UIAlertControllerStyle.alert)

    let cancelAction = UIAlertAction(title: "OK",
                                     style: .cancel, handler: nil)

    alert.addAction(cancelAction)
    self.presentViewController(alert, animated: true, completion: nil)
}

I get an error saying that there is an extra argument animated in the presentViewController method, but when I take it out, it still doesn't dismiss the error, and then I'm told that completion is an extra argument.

Nirav D
  • 71,513
  • 12
  • 161
  • 183
BlackHatSamurai
  • 23,275
  • 22
  • 95
  • 156

6 Answers6

27

presentViewController is changed in Swift 3 like this.

present(alert, animated: true)

Check Apple Documentation for more details.

From Swift 3 completionis optional so if you doesn't want handle the completion block no need to write nil for that and if you want to handle completion block then write like this.

self.present(alert, animated: true) { 

}

Note: Your notifyUser method is declared with static so you cannot use self with it so remove that also to remove the next error that you get after correcting this one.

Nirav D
  • 71,513
  • 12
  • 161
  • 183
  • 3
    Thanks man. This whole swift 3 has me sideways! I appreciate it! – BlackHatSamurai Oct 15 '16 at 05:58
  • @BlackHatSamurai Welcome mate :) – Nirav D Oct 15 '16 at 05:58
  • Your solution is standard but your answer is not as per question. He is try to present a view controller using self in a static method. thats why he get an error of completion is an extra argument – Syed Qamar Abbas Jun 13 '17 at 09:36
  • @SyedQamarAbbas Have you read the question, if not read it again then you get idea that op is using old `presentViewController` method that is not available any more in Swift 3 it is renamed as `present(_ viewController:)` before down voting at least read the question, If OP still getting error then he will never mark this as accepted answer – Nirav D Jun 13 '17 at 09:41
  • I know he said that UIAlertController is not working in swift 3.0 but he displayed the error as well. If i follow your answer and use self in a static method then i will get that error again. Please try it. – Syed Qamar Abbas Jun 13 '17 at 09:46
  • @SyedQamarAbbas I haven't looked at static but that not the question here, If question is about static error then down voting my answer might be legal but here it don't seems to be ok – Nirav D Jun 13 '17 at 09:48
  • @SyedQamarAbbas I have also edited My answer but I'm sure you need to at least add the comment instead of directly down voting answer as of this is not the question asked by OP. – Nirav D Jun 13 '17 at 10:00
27
 let actionSheetController: UIAlertController = UIAlertController(title: "Action Sheet", message: "Swiftly Now! Choose an option!", preferredStyle: .alert)
 let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in
            //Just dismiss the action sheet
        }
 actionSheetController.addAction(cancelAction)
 self.present(actionSheetController, animated: true, completion: nil)
Shardul
  • 4,266
  • 3
  • 32
  • 50
Himanshu Moradiya
  • 4,769
  • 4
  • 25
  • 49
11

Swift 3

let alertView = UIAlertController(title: "", message: "your message", preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default, handler: { (alert) in

})
alertView.addAction(action)
self.present(alertView, animated: true, completion: nil)
Pang
  • 9,564
  • 146
  • 81
  • 122
Giang
  • 3,553
  • 30
  • 28
4

You are trying to use self in a static method while self should be the current instance of that class but static cannot use self.

Without Action Handler For Alert Button

In Obj-C

+(void) notifyUser:(NSString *)title withMessage:(NSString *)message onViewController:(UIViewController *)vc {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *action = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
    [alert addAction:action];
    //vc will be the view controller on which you will present your alert as you cannot use self because this method is static.
    [vc presentViewController:alert animated:true completion:nil];
}

In Swift 3.0

static func notifyUser(_ title: String, message: String, vc: UIViewController) -> Void
    {
        let alert = UIAlertController(title: title,
                                      message: message,
                                      preferredStyle: UIAlertControllerStyle.alert)

        let cancelAction = UIAlertAction(title: "OK",
                                         style: .cancel, handler: nil)

        alert.addAction(cancelAction)
        //vc will be the view controller on which you will present your alert as you cannot use self because this method is static.
        vc.present(alert, animated: true, completion: nil)
    }

With Action Handler For Alert Button

In Obj-C

+(void) notifyUser:(NSString *)title withMessage:(NSString *)message withButtonTitles:(NSArray<NSString *> *)buttonTitles andButtonStyles:(NSArray *)styles onViewController:(UIViewController *)vc onCompletion:(void (^)(NSInteger))completion  {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];

    for (NSString *title in buttonTitles) {
        UIAlertActionStyle style = [[styles objectAtIndex:[buttonTitles indexOfObject:title]] intValue];

        UIAlertAction *actionObj = [UIAlertAction actionWithTitle:title style:style handler:^(UIAlertAction *action){
            NSInteger index = [buttonTitles indexOfObject:action.title];
            completion(index);
        }];
        [alert addAction:actionObj];
    }
    //vc will be the view controller on which you will present your alert as you cannot use self because this method is static.
    [vc presentViewController:alert animated:true completion:nil];
}

Invoke above instance method like this.

[ClassName notifyUser:@"Title For Alert" withMessage:@"Message for Alert" withButtonTitles:@[@"Camera",@"Library",@"Dismiss"] andButtonStyles:@[@(UIAlertActionStyleDefault),@(UIAlertActionStyleDefault),@(UIAlertActionStyleCancel)] onViewController:yourViewController onCompletion:^(NSInteger indexOfTappedButton){
                    //Note the index of the button will have the same order as you have provide the titles array in this method
    }];

Here yourViewController is the controller on which you will present this Alert

In Swift 3.0

extension UIAlertController {
    static func notifyUser(_ title: String, message: String, alertButtonTitles: [String], alertButtonStyles: [UIAlertActionStyle], vc: UIViewController, completion: @escaping (Int)->Void) -> Void
    {
        let alert = UIAlertController(title: title,
                                      message: message,
                                      preferredStyle: UIAlertControllerStyle.alert)

        for title in alertButtonTitles {
            let actionObj = UIAlertAction(title: title,
                                          style: alertButtonStyles[alertButtonTitles.index(of: title)!], handler: { action in
                                            completion(alertButtonTitles.index(of: action.title!)!)
            })

            alert.addAction(actionObj)
        }


        //vc will be the view controller on which you will present your alert as you cannot use self because this method is static.
        vc.present(alert, animated: true, completion: nil)
    }
}

Invoke above static method like this.

UIAlertController.notifyUser("Title for Alert", message: "Message show in Alert", alertButtonTitles: ["Camera", "Library","Dismiss"], alertButtonStyles: [.default,.default,.cancel], vc: yourViewController, completion: { indexOfTappedButton in
            //Note the index of the button will have the same order as you have provide the titles array in this method
        })

Here yourViewController is the controller on which you will present this Alert

Syed Qamar Abbas
  • 3,637
  • 1
  • 28
  • 52
  • If you look at his code you'll know that he wants to show alert in static method but his title shows that he also want the solution in swift 3. So i complete both. – Syed Qamar Abbas Jun 13 '17 at 10:10
  • This is doesn't about down voting or up voting it is about question I have just suggested solution about error that is posted in question not anything else. – Nirav D Jun 13 '17 at 10:12
  • You have posted the solution only with respect to question title. your solution doesn't target the actual answer/solution to that error. – Syed Qamar Abbas Jun 13 '17 at 10:14
  • I have already answer to the error that is posted in question but doesn't see the `static` this error is related to Swift 3 change not with the **static** – Nirav D Jun 13 '17 at 10:17
2

Swift 3 Try Custom Action Cancel

  let uiAlertController = UIAlertController(// create new instance alert  controller
          title: "You TITLE text",
          message: "You Message text", 
          preferredStyle:.alert)

    uiAlertController.addAction(// add Custom action on Event is Cancel
    UIAlertAction.init(title: "Cancel", style: .default, handler: { (UIAlertAction) in
       //TO DO code
       uiAlertController.dismiss(animated: true, completion: nil)//dismiss show You alert, on click is Cancel
    }))
    //show You alert
    self.present(uiAlertController, animated: true, completion: nil)
amiron
  • 721
  • 9
  • 11
0
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
if action {
    alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: {
        (action : UIAlertAction!) in self.navigationController?.popViewController(animated: true)
    }))
} else {
    alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
}
self.present(alert, animated: true, completion: nil)
Ignacio Ara
  • 2,476
  • 2
  • 26
  • 37