27

I'm working on a ViewController with code (no storyboard). I'm trying to add and AlertController

I have declare propery in .m

@property (nonatomic, strong) UIAlertController *alertController;

And init in loadview method

//alertviewController
    _alertController = [[UIAlertController alloc]initWithNibName:nil bundle:nil];

And call the alertview in viewDidLoad:

_alertController = [UIAlertController alertControllerWithTitle:@"Error display content" message:@"Error connecting to server, no local database" preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                LandingPageViewController *viewController = [[LandingPageViewController alloc] initWithNibName:nil bundle:nil];
    //            viewController.showNavBarBackButton = YES;
                [[AppDelegate sharedAppDelegate].rootViewController cPushViewController:viewController];
}];
[_alertController addAction:ok];
[self presentViewController:_alertController animated:YES completion:nil];

I dont' know why the alert is not showing up. Some thing wrong with my code. How to set up and call alertViewController programmatically?

Naresh
  • 16,698
  • 6
  • 112
  • 113
Lê Khánh Vinh
  • 2,591
  • 5
  • 31
  • 77
  • Hi tried but there is error no visible interface for 'UIAlertController' declares the selector 'show'. [_alertController show]; – Lê Khánh Vinh Aug 01 '16 at 15:16
  • Remove this line `_alertController = [[UIAlertController alloc]initWithNibName:nil bundle:nil];` I'm not sure if that will fix the problem, but it's not needed, especially not in `loadView`, (did you mean `viewDidLoad`?) – James P Aug 01 '16 at 15:18
  • try calling this alert in viewDidAppear – Eugene Gordin Aug 01 '16 at 15:21
  • Hi i put the calling code in viewdidAppear the alert show up but crash with this error: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller .' – Lê Khánh Vinh Aug 01 '16 at 15:25
  • it probably crashes on the button tap. which means make sure the alert dismisses and then the push takes place. call the push after delay – Shubhank Aug 01 '16 at 15:45
  • are you testing with the simulator or with a real device and what is the ios version – caldera.sac Aug 01 '16 at 15:50
  • I call the method by putting all the creation and call in viewdidappear. but can not call in viewdidload. i'm working with simulator ios 9.3 – Lê Khánh Vinh Aug 01 '16 at 15:57
  • Have you put any breakpoints into your code to follow the execution path and make sure that what you think is happening is actually happening. – Abizern Aug 01 '16 at 15:59
  • I thinks the problem is that can not call present view controller in viewdidload. If i put the call in other place everything working fine! – Lê Khánh Vinh Aug 01 '16 at 16:01
  • Did you try checking out the new Documentation feature of Stackoverflow? This is extensively covered [here](http://stackoverflow.com/documentation/ios/874/uialertcontroller/2949/alert-views-with-uialertcontroller#t=201608020610222402166). – NSNoob Aug 02 '16 at 06:10
  • https://stackoverflow.com/questions/24022479/how-would-i-create-a-uialertview-in-swift – Naresh Sep 24 '19 at 05:08

4 Answers4

72
- (void)logoutButtonPressed
{
     UIAlertController * alert = [UIAlertController
                                 alertControllerWithTitle:@"Logout"
                                 message:@"Are You Sure Want to Logout!"
                                 preferredStyle:UIAlertControllerStyleAlert];

    //Add Buttons

    UIAlertAction* yesButton = [UIAlertAction
                                actionWithTitle:@"Yes"
                                style:UIAlertActionStyleDefault
                                handler:^(UIAlertAction * action) {
                                    //Handle your yes please button action here
                                    [self clearAllData];
                                }];

    UIAlertAction* noButton = [UIAlertAction
                               actionWithTitle:@"Cancel"
                               style:UIAlertActionStyleDefault
                               handler:^(UIAlertAction * action) {
                                   //Handle no, thanks button
                               }];

    //Add your buttons to alert controller

    [alert addAction:yesButton];
    [alert addAction:noButton];

    [self presentViewController:alert animated:YES completion:nil];
}
Graham
  • 7,431
  • 18
  • 59
  • 84
ChenSmile
  • 3,401
  • 4
  • 39
  • 69
  • hi where to call the [self presentViewController:alert animated:YES completion:nil]; seem can not call in viewdidload – Lê Khánh Vinh Aug 01 '16 at 16:06
  • Hi it working when i create separate method and call in viewdidload but there a warning in console: Presenting view controllers on detached view controllers is discouraged – Lê Khánh Vinh Aug 01 '16 at 16:08
  • where r u performing ur alert controller, it may be button click or on some method, use above complete code in one method and call it in ur desire place. hope u got it – ChenSmile Aug 01 '16 at 16:09
  • Hi my purpose is when user come to the viewcontroller the app will check whether coredata has record or not. if not and there is no internet connection . the app will show an error "no databae no internet connection" and move to home page! – Lê Khánh Vinh Aug 01 '16 at 16:12
  • @LêKhánhVinh it is not good to have alert view controller in viewDidLoad. u can check after view get loaded – ChenSmile Aug 01 '16 at 16:13
  • Hi so where is good place to put it when user come to that viewcontroller? – Lê Khánh Vinh Aug 01 '16 at 16:18
  • @LêKhánhVinh check here ... http://stackoverflow.com/questions/26554894/how-to-present-uialertcontroller-when-not-in-a-view-controller – ChenSmile Aug 01 '16 at 16:22
  • Hi I found it only working good when we put in viewDidAppear. Everything seem working fine when move code to show UIalertViewController in viewDidAppear – Lê Khánh Vinh Aug 02 '16 at 01:46
7

In Xcode 9.4.1

Create alert function globally and use every where.

//Alert function
- (void) showAlertMsg:(UIViewController *)viewController title:(NSString *)title message:(NSString *)message {

    UIAlertController * alert = [UIAlertController alertControllerWithTitle : title
                                                                    message : message
                                                             preferredStyle : UIAlertControllerStyleAlert];

    UIAlertAction * ok = [UIAlertAction
                          actionWithTitle:@"OK"
                          style:UIAlertActionStyleDefault
                          handler:^(UIAlertAction * action)
                          { }];

    [alert addAction:ok];
    dispatch_async(dispatch_get_main_queue(), ^{
        [viewController presentViewController:alert animated:YES completion:nil];
    });

}

Call like this in your required place.

Import that class and create instance

//Ex:
GlobalClassViewController *gcvc = [[GlobalClassViewController alloc]init];

//Call alert function with instance
[gcvc showAlertMsg:self title:@"" message:placeholderText];

How would I create a UIAlertView in Swift?

Deepzz
  • 4,573
  • 1
  • 28
  • 52
Naresh
  • 16,698
  • 6
  • 112
  • 113
  • The dispatch_async helped me get past some issues where my alerts weren't appearing because they were inadvertently created on view which were going out of scope. – ja928 Jul 23 '20 at 21:48
  • The dispatch_async is necessary in iOS13+ with UISplitViewController on iPad (no scenes, no Storyboards). It is not required in iOS12 and lower. UI just locks up without showing the alert otherwise. – ghr Aug 20 '22 at 05:35
2

And in Swift >=3:

  let alertController = UIAlertController(title: "Some Error",
                                               message: "Pleas confirm?",
                                               preferredStyle: .alert)

  let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil)
            alertController.addAction(defaultAction)

  self?.present(alertController, animated: true, completion: nil)
carbonr
  • 6,049
  • 5
  • 46
  • 73
Ethan Parker
  • 2,986
  • 1
  • 23
  • 29
  • 1
    hi so where is the place to place the code whenever user come to that viewcontroller and app has finished checked for some logic (for example no coredata to show?) – Lê Khánh Vinh Aug 01 '16 at 16:20
  • It's up to you, you can put it in viewDidLoad if you'd like it to be displayed when the user comes to that view or you can have it fired on a certain button press via IBAction – Ethan Parker Aug 01 '16 at 20:52
  • 1
    Hi i found put on view did load not working for alertViewController. Need to be in viewDidAppear – Lê Khánh Vinh Aug 02 '16 at 01:22
  • Nice catch, that will work or it should also work as an IBAction – Ethan Parker Aug 05 '16 at 18:03
0

Create global Alert controller that is accessible in all view controllers using extension.
Create an extension of UIViewController with your function to display alert with required parameter arguments.

extension UIViewController {

      func displayalert(title:String, message:String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction((UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in

            alert.dismiss(animated: true, completion: nil)

        })))

        self.present(alert, animated: true, completion: nil)


      }
}


Now call this function from your view controller:

class TestViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.displayalert(title: <String>, message: <String>)
    }
}
Krunal
  • 77,632
  • 48
  • 245
  • 261