How would I create a UIAlertView in Swift?
Asked Answered
M

36

561

I have been working to create a UIAlertView in Swift, but for some reason I can't get the statement right because I'm getting this error:

Could not find an overload for 'init' that accepts the supplied arguments

Here is how I have it written:

let button2Alert: UIAlertView = UIAlertView(title: "Title", message: "message",
                     delegate: self, cancelButtonTitle: "OK", otherButtonTitles: nil)

Then to call it I'm using:

button2Alert.show()

As of right now it is crashing and I just can't seem to get the syntax right.

Marisolmarissa answered 3/6, 2014 at 18:35 Comment(4)
UIAlertView and UIActionSheet has been replaced by UIAlertController in iOS 8, have you looked at this?Norite
Make sure the class that self belongs to adopts the protocol UIAlertViewDelegate (the recommended way to do this, in Swift, is with an extension).Schoof
@Adam: I have reverted your retagging. The swift3 tag is for "questions directly related to changes in version 3 of Apple's Swift programming language." And I don't think that "If the answers make it clear that the problem in the question was caused by something other than what the asker thought, retagging is very helpful." from meta.#252579 applies here.Unrepair
@MartinR I don't know how questions can be updated to show that there are answers that apply to a current version of Swift; there is a lot of old, useless stuff here and [swift] finds it all along with the useful. I don't feel strongly about this retag being reverted but I wish there was a definitive way to solve this problem. (I wish answers had tags.)Haphtarah
B
1008

From the UIAlertView class:

// UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead

On iOS 8, you can do this:

let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)

Now UIAlertController is a single class for creating and interacting with what we knew as UIAlertViews and UIActionSheets on iOS 8.

Edit: To handle actions:

alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { action in
    switch action.style{
    case .Default:
        print("default")
        
    case .Cancel:
        print("cancel")
        
    case .Destructive:
        print("destructive")
    }
}}))

Edit for Swift 3:

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

Edit for Swift 4.x:

let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
    switch action.style{
        case .default:
        print("default")
        
        case .cancel:
        print("cancel")
        
        case .destructive:
        print("destructive")
        
    }
}))
self.present(alert, animated: true, completion: nil)
Bhili answered 3/6, 2014 at 18:48 Comment(9)
Where did you see that UIAlertView is deprecated? I don't see that in the documentation?Marisolmarissa
Cmd + Click the UIAlertView class, and the comment is right on top of the class declaration.Bhili
I'll answer my own question for anyone else who's curious alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: { (ACTION :UIAlertAction!)in }))Sallyanne
What's the point of Cancel and Destructive cases since it will always be what you specified .Default?Huehuebner
Under what context, would the completion be not nil in self.presentViewController(alert, animated: true, completion: nil) . Any samples?Plumage
@s1u, completion is just a block (Void -> Void)? that is executed when the view controller is done presenting.Bhili
I think your example is a confusing one or at least that I don't understand it usefulness. The style of the action is already default. There is no reason for you to switch over it in your closure. It will ALWAYS go to default. Can you make your example more meaningful so that we would know why the closure takes action as a parameter?Testify
Reading this answer the switch case you did is unnecessary. The switch is only useful if the type, or title aren't hardcoded ie they are dynamic: You might have a series of dynamic buttons so the titles are not hardcoded. And then the handler might need to pass the chosen title off to some other method callTestify
Can you add the SwiftUI version?Vertebra
G
561

One Button

One Button Screenshot

class ViewController: UIViewController {

    @IBAction func showAlertButtonTapped(_ sender: UIButton) {

        // create the alert
        let alert = UIAlertController(title: "My Title", message: "This is my message.", preferredStyle: UIAlertController.Style.alert)

        // add an action (button)
        alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))

        // show the alert
        self.present(alert, animated: true, completion: nil)
    }
}

Two Buttons

Two Button Alert Screenshot

class ViewController: UIViewController {

    @IBAction func showAlertButtonTapped(_ sender: UIButton) {

        // create the alert
        let alert = UIAlertController(title: "UIAlertController", message: "Would you like to continue learning how to use iOS alerts?", preferredStyle: UIAlertController.Style.alert)

        // add the actions (buttons)
        alert.addAction(UIAlertAction(title: "Continue", style: UIAlertAction.Style.default, handler: nil))
        alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: nil))

        // show the alert
        self.present(alert, animated: true, completion: nil)
    }
}

Three Buttons

enter image description here

class ViewController: UIViewController {

    @IBAction func showAlertButtonTapped(_ sender: UIButton) {

        // create the alert
        let alert = UIAlertController(title: "Notice", message: "Lauching this missile will destroy the entire universe. Is this what you intended to do?", preferredStyle: UIAlertController.Style.alert)

        // add the actions (buttons)
        alert.addAction(UIAlertAction(title: "Remind Me Tomorrow", style: UIAlertAction.Style.default, handler: nil))
        alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: nil))
        alert.addAction(UIAlertAction(title: "Launch the Missile", style: UIAlertAction.Style.destructive, handler: nil))

        // show the alert
        self.present(alert, animated: true, completion: nil)
    }
}

Handling Button Taps

The handler was nil in the above examples. You can replace nil with a closure to do something when the user taps a button. For example:

alert.addAction(UIAlertAction(title: "Launch the Missile", style: UIAlertAction.Style.destructive, handler: { action in

    // do something like...
    self.launchMissile()

}))

Notes

  • Multiple buttons do not necessarily need to use different UIAlertAction.Style types. They could all be .default.
  • For more than three buttons consider using an Action Sheet. The setup is very similar. Here is an example.
Galatea answered 26/10, 2015 at 7:44 Comment(2)
is there any delegate property in UIAlertController? in UIAlertView there is a delegate property which we sometime set to self, Is there any nothing like this in UIAlertController?? I am New , please help meBlastopore
Beautiful answer - Now how can we switch to a new view within the handler?Welldone
M
117

You can create a UIAlert using the standard constructor, but the 'legacy' one seems to not work:

let alert = UIAlertView()
alert.title = "Alert"
alert.message = "Here's a message"
alert.addButtonWithTitle("Understood")
alert.show()
Mcclelland answered 3/6, 2014 at 18:52 Comment(4)
UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead.Cutinize
@Cutinize UIAlertController is only available from iOS 8 onwards, please also mention that when suggesting its use. There are situations where iOS7 support is still desired and people might miss the problem. Deprecation doesn't mean "don't ever use this anymore."Mafaldamafeking
This works if your app is still targeting iOS 7. However, ideally UIAlertView should only be used when UIAlertController is not available. if NSClassFromString("UIAlertController") != nil { /* use UIAlertController * / } else { /* use UIAlertView * / }Riegel
UIAlertview() is now deprecated in iOS 9Gravy
A
50

In Swift 4.2 and Xcode 10

Method 1 :

SIMPLE ALERT

let alert = UIAlertController(title: "Your title", message: "Your message", preferredStyle: .alert)
    
     let ok = UIAlertAction(title: "OK", style: .default, handler: { action in
     })
     alert.addAction(ok)
     let cancel = UIAlertAction(title: "Cancel", style: .default, handler: { action in
     })
     alert.addAction(cancel)
     DispatchQueue.main.async(execute: {
        self.present(alert, animated: true)
})

Method 2 :

ALERT WITH SHARED CLASS

If you want Shared class style(Write once use every where)

import UIKit
class SharedClass: NSObject {//This is shared class
static let sharedInstance = SharedClass()

    //Show alert
    func alert(view: UIViewController, title: String, message: String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { action in
        })
        alert.addAction(defaultAction)
        DispatchQueue.main.async(execute: {
            view.present(alert, animated: true)
        })
    }

    private override init() {
    }
}

Now call alert like this in every ware

SharedClass.sharedInstance.alert(view: self, title: "Your title here", message: "Your message here")

Method 3 :

PRESENT ALERT TOP OF ALL WINDOWS

If you want to present alert on top of all views, use this code

func alertWindow(title: String, message: String) {
    DispatchQueue.main.async(execute: {
        let alertWindow = UIWindow(frame: UIScreen.main.bounds)
        alertWindow.rootViewController = UIViewController()
        alertWindow.windowLevel = UIWindowLevelAlert + 1
    
        let alert2 = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let defaultAction2 = UIAlertAction(title: "OK", style: .default, handler: { action in
        })
        alert2.addAction(defaultAction2)
    
        alertWindow.makeKeyAndVisible()
    
        alertWindow.rootViewController?.present(alert2, animated: true, completion: nil)
    })
}

Function calling

SharedClass.sharedInstance.alertWindow(title:"This your title", message:"This is your message")

Method 4 :

Alert with Extension

extension  UIViewController {

    func showAlert(withTitle title: String, withMessage message:String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let ok = UIAlertAction(title: "OK", style: .default, handler: { action in
        })
        let cancel = UIAlertAction(title: "Cancel", style: .default, handler: { action in
        })
        alert.addAction(ok)
        alert.addAction(cancel)
        DispatchQueue.main.async(execute: {
            self.present(alert, animated: true)
        })
    }
}

Now call like this

//Call showAlert function in your class
@IBAction func onClickAlert(_ sender: UIButton) {
    showAlert(withTitle:"Your Title Here", withMessage: "YourCustomMessageHere")
}

Method 5 :

ALERT WITH TEXTFIELDS

If you want to add textfields to alert.

//Global variables
var name:String?
var login:String?

//Call this function like this:  alertWithTF() 
//Add textfields to alert 
func alertWithTF() {
    
    let alert = UIAlertController(title: "Login", message: "Enter username&password", preferredStyle: .alert)
    // Login button
    let loginAction = UIAlertAction(title: "Login", style: .default, handler: { (action) -> Void in
        // Get TextFields text
        let usernameTxt = alert.textFields![0]
        let passwordTxt = alert.textFields![1]
        //Asign textfileds text to our global varibles
        self.name = usernameTxt.text
        self.login = passwordTxt.text
        
        print("USERNAME: \(self.name!)\nPASSWORD: \(self.login!)")
    })
    
    // Cancel button
    let cancel = UIAlertAction(title: "Cancel", style: .destructive, handler: { (action) -> Void in })
    
    //1 textField for username
    alert.addTextField { (textField: UITextField) in
        textField.placeholder = "Enter username"
        //If required mention keyboard type, delegates, text sixe and font etc...
        //EX:
        textField.keyboardType = .default
    }
    
    //2nd textField for password
    alert.addTextField { (textField: UITextField) in
        textField.placeholder = "Enter password"
        textField.isSecureTextEntry = true
    }
    
    // Add actions
    alert.addAction(loginAction)
    alert.addAction(cancel)
    self.present(alert, animated: true, completion: nil)
    
}

Method 6:

Alert in SharedClass with Extension

//This is your shared class
import UIKit

 class SharedClass: NSObject {

 static let sharedInstance = SharedClass()

 //Here write your code....

 private override init() {
 }
}

//Alert function in shared class
extension UIViewController {
    func showAlert(title: String, msg: String) {
        DispatchQueue.main.async {
            let alert = UIAlertController(title: title, message: msg, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }
}

Now call directly like this

self.showAlert(title: "Your title here...", msg: "Your message here...")

Method 7:

Alert with out shared class with Extension in separate class for alert.

Create one new Swift class, and import UIKit. Copy and paste below code.

//This is your Swift new class file
import UIKit
import Foundation

extension UIAlertController {
    class func alert(title:String, msg:String, target: UIViewController) {
        let alert = UIAlertController(title: title, message: msg, preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default) {
        (result: UIAlertAction) -> Void in
        })
        target.present(alert, animated: true, completion: nil)
    }
}

Now call alert function like this in all your classes (Single line).

UIAlertController.alert(title:"Title", msg:"Message", target: self)

How is it....

Anticatalyst answered 16/8, 2018 at 12:17 Comment(8)
Perfekt! +1 Could you please add a method with an integrated timeout? Thanks!Hieratic
@ Passe, sorry I can't understood, can please explain briefly.Anticatalyst
I need an alertController which is presented until the 'OK' button is clicked or a timeout occurred. Something like method 6 or 7 but with an additional input variable 'timeout'.Hieratic
extension UIViewController { func alertWithTime(title: String, msg: String, timeInterval:TimeInterval) { DispatchQueue.main.async { let alert = UIAlertController(title: title, message: msg, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) self.present(alert, animated: true, completion: nil) if #available(iOS 10.0, *) { Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: false, block: { _ in alert.dismiss(animated: true, completion: nil) }) } else {// Fallback on earlier versions}}}}Anticatalyst
Call like this self.alertWithTime(title: "Title", msg: "Message", timeInterval:3.0)//Display 3 secondsAnticatalyst
Here this timer code can work from iOS 10 and higher versions.Anticatalyst
If you mention timeInterval 0 in that case if you don't want to close alert, use if condition. if timeInterval != 0 { if #available(iOS 10.0, *) { Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: false, block: { _ in alert.dismiss(animated: true, completion: nil) }) } else { // Fallback on earlier versions } }Anticatalyst
nice solutions. In method 2, "SharedClass.SharedInstance..." have to be "SharedClass.sharedInstance...".Eelgrass
A
20

Click of View

@IBAction func testClick(sender: UIButton) {

  var uiAlert = UIAlertController(title: "Title", message: "Message", preferredStyle: UIAlertControllerStyle.Alert)
  self.presentViewController(uiAlert, animated: true, completion: nil)

  uiAlert.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { action in
   println("Click of default button")
  }))

  uiAlert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { action in
   println("Click of cancel button")
  }))

}

Done with two buttons OK & Cancel

Ashmore answered 10/5, 2015 at 16:15 Comment(1)
very helpful for me.Diaphone
C
12

If you're targeting iOS 7 and 8, you need something like this to make sure you're using the right method for each version, because UIAlertView is deprecated in iOS 8, but UIAlertController is not available in iOS 7:

func alert(title: String, message: String) {
    if let getModernAlert: AnyClass = NSClassFromString("UIAlertController") { // iOS 8
        let myAlert: UIAlertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
        myAlert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
        self.presentViewController(myAlert, animated: true, completion: nil)
    } else { // iOS 7
        let alert: UIAlertView = UIAlertView()
        alert.delegate = self

        alert.title = title
        alert.message = message
        alert.addButtonWithTitle("OK")

        alert.show()
    }
}
Communist answered 13/1, 2015 at 21:14 Comment(3)
Or you can save time and just use UIAlertView until you drop support for iOS 7. Apple won't reject your app for that.Decanal
Deprecation doesn't mean "don't use this" or that it would be the "wrong method", it just means it will not work later on. There's no need to specifically use UIAlertController on iOS8 if one just needs basic alerts. They will work as before. There are many APIs that have been deprecated in iOS4 or 5 and still work in iOS8. But of course apps targeting a higher iOS level should not use them and that's why there is a deprecation warning.Mafaldamafeking
@SamiKuhmonen No, but it makes it clearer why you're doing what you're doing and makes it easier to remove support for deprecated methods when your minimum version is high enough to do so.Communist
S
12

With the protocol extensions of Swift 2, you can make a protocol that provides a default implementation to your view controllers:

ShowsAlert.swift

import UIKit

protocol ShowsAlert {}

extension ShowsAlert where Self: UIViewController {
    func showAlert(title: String = "Error", message: String) {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
        alertController.addAction(UIAlertAction(title: "Ok", style: .Default, handler: nil))
        presentViewController(alertController, animated: true, completion: nil)
    }
}

ViewController.swift

class ViewController: UIViewController, ShowsAlert {
    override func viewDidLoad() {
        super.viewDidLoad()
        showAlert(message: "Hey there, I am an error message!")
    }
}
Sc answered 7/10, 2015 at 13:33 Comment(1)
Works perfectly. For Swift3 change 'presentViewController' to 'present'.Gibby
M
11

Show UIAlertView in swift language :-

Protocol UIAlertViewDelegate

let alert = UIAlertView(title: "alertView", message: "This is alertView", delegate:self, cancelButtonTitle:"Cancel", otherButtonTitles: "Done", "Delete")
alert.show()

Show UIAlertViewController in swift language :-

let alert = UIAlertController(title: "Error", message: "Enter data in Text fields", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
Monteiro answered 3/9, 2014 at 12:53 Comment(0)
C
11

Simply do not provide otherButtonTitles in the constructor.

let alertView = UIAlertView(title: "Oops!", message: "Something
happened...", delegate: nil, cancelButtonTitle: "OK")

alertView.show()

But I do agree with Oscar, this class is deprecated in iOS 8, so there won't be no use of UIAlertView if you're doing an iOS 8 only app. Otherwise the code above will work.

Corcovado answered 22/12, 2014 at 14:51 Comment(0)
M
11

AlertView Swift 5 and above:-

let alert = UIAlertController(title: LocalizedStringConstant.alert, message: message, preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "Retry", style: .cancel, handler: { (_) in
     }))
self.present(alert, animated: true, completion: nil)
Metic answered 10/7, 2020 at 5:1 Comment(0)
A
10

For SWIFT4, I think, extending UIViewController and creating a reusable confirmation control is the most elegant way.

You can extend the UIViewController as below:

extension UIViewController {

func AskConfirmation (title:String, message:String, completion:@escaping (_ result:Bool) -> Void) {
    let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
    self.present(alert, animated: true, completion: nil)

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

    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { action in
        completion(false)
    }))
  }
}

Then you can use it anytime:

 AskConfirmation(title: "YOUR MESSAGE TITLE", message: "YOUR MESSAGE") { (result) in
        if result { //User has clicked on Ok

        } else { //User has clicked on Cancel

        }
    }
Abebi answered 20/1, 2018 at 15:4 Comment(0)
L
9

I found this one,

var alertView = UIAlertView();
alertView.addButtonWithTitle("Ok");
alertView.title = "title";
alertView.message = "message";
alertView.show();

not good though, but it works :)

Update:

but I have found on header file as:

extension UIAlertView {
    convenience init(title: String, message: String, delegate: UIAlertViewDelegate?, cancelButtonTitle: String?, otherButtonTitles firstButtonTitle: String, _ moreButtonTitles: String...)
}

somebody may can explain this.

Lucialucian answered 3/6, 2014 at 19:5 Comment(3)
Apparently UIAlertView has been deprecated in iOS 8 and we now use UIAlertController with a preferred style of UIAlertControllerStyleAlert.Marisolmarissa
If you run an app that needs to be backwards compatible to iOS7.1 and you're writing it in Swift, the UIAlertController will crash the target device. You need to support the legacy UIAlertViews for iOS7.Hurd
I think that it's not Swift that would cause a crash, but rather the fact that the UIAlertController is not available before iOS 8Acrospire
C
7

For iOS 13 Xcode 11+ Swift 5.X

UIAlertController can now provide Alerts as well as Action Sheets

Alerts

// First instantiate the UIAlertController

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


 // Add action buttons to it and attach handler functions if you want to 

 alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
 alert.addAction(UIAlertAction(title: "Just Do It!", style: .destructive, handler: nil))
 alert.addAction(UIAlertAction(title: "Maybe", style: .default, handler: nil))

// Show the alert by presenting it

self.present(alert, animated: true)

Note that it's is a fundamental nature for all action buttons to dismiss the alert view when tapped. The style parameter is just for deciding the color of the text (and some default order in which the buttons should appear which ofc can be changed)

A sample handler function could be

func handler(_ action: UIAlertAction) { 

   if action.title == 'Title' {
       // do stuff
   }

}

As a side note, I would say instead of making 3 different handlers you can just make 1 and trace back to the element which provoked it in the manner shown above We can also check alert.style but that again we can have multiple .default styled actions , I wouldn't recommend that

Action Sheets

The explanation is similar because the main difference here is that an alert interrupts the user whereas an action sheet slides from the bottom in an iPhone and appears as a popover in an iPad

The Purpose of action sheets is to guide the users in deciding his actions based on their current state. So you gotta treat action sheets like crossroads !. There is generally no message and the title is rendered as caption sized text

let action = UIAlertController(title: "What do you want to do with the message",
                               message: nil,
                               preferredStyle: .actionSheet)

action.addAction(UIAlertAction(title: "Cancel", style: .cancel)) 

for act in ["Save", "Post", "Discard"] {  
          action.addAction(UIAlertAction(title: act, style: .default, handler: nil))
}

self.present(action, animated: true)

The above code is going to work for an iPhone but will crash at runtime for an iPad because UIPopoverPresentationController is going to take charge of the alert and it won't be referencing anything at that time. So to avoid that you will have to provide the following chunk of code its mandatory

if let pop = action.popoverPresentationController {

     let v = sender as! UIView 
     pop.sourceView = v 
     pop.sourceRect = v.bounds
 }

Also in case of iPad tapping on anywhere outside the popover will dismiss it and the completion handler of .cancel action button will be called.

Hope that helps :) That being said, comment down below if you have any doubts

Clinkscales answered 1/1, 2020 at 16:8 Comment(1)
Self in the context of view controllerClinkscales
R
5
    class Preview: UIViewController , UIAlertViewDelegate
    {
        @IBAction func MoreBtnClicked(sender: AnyObject)
        {
            var moreAlert=UIAlertView(title: "Photo", message: "", delegate: self, cancelButtonTitle: "No Thanks!", otherButtonTitles: "Save Image", "Email", "Facebook", "Whatsapp" )
            moreAlert.show()
            moreAlert.tag=111;
        }

        func alertView(alertView: UIAlertView, didDismissWithButtonIndex buttonIndex: Int)
        {
            if alertView.tag==111
            {
                if buttonIndex==0
                {
                    println("No Thanks!")
                }
                else if buttonIndex==1
                {
                    println("Save Image")
                }
                else if buttonIndex == 2
                {
                    println("Email")
                }
                else if buttonIndex == 3
                {
                    println("Facebook")
                }
                else if buttonIndex == 4
                {
                    println("Whatsapp")
                }
            }
        }
    }
Rimola answered 10/7, 2015 at 12:35 Comment(1)
Just writing a lump of code is not very useful. When answering any question (specially an old question with several answers including an accepted answer) please write more than a piece of code. Please add an explanation of what your code does, how it answers the question and how it is different (or better) than the other answers.Kolivas
C
5

I have another trick. Suppose you have 5 classes where a logout alert to be applied. Try with swift class extension.

File- New- Swift class- Name it.

Add the following:

public extension UIViewController
{

    func makeLogOutAlert()
    {
        var refreshAlert = UIAlertController(title: "Log Out", message: "Are You Sure to Log Out ? ", preferredStyle: UIAlertControllerStyle.Alert)

        refreshAlert.addAction(UIAlertAction(title: "Confirm", style: .Default, handler: { (action: UIAlertAction!) in
            self.navigationController?.popToRootViewControllerAnimated(true)
        }))

        refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .Default, handler: { (action: UIAlertAction!) in
            refreshAlert .dismissViewControllerAnimated(true, completion: nil)
        }))

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

Implement using : self.makeLogOutAlert(). Hope it helps.

Clarettaclarette answered 17/9, 2015 at 13:48 Comment(0)
D
5

I have made a singleton class to make this convenient to use from anywhere in your app: https://github.com/Swinny1989/Swift-Popups

You can then create a popup with multiple buttons like this:

Popups.SharedInstance.ShowAlert(self, title: "Title goes here", message: "Messages goes here", buttons: ["button one" , "button two"]) { (buttonPressed) -> Void in
    if buttonPressed == "button one" { 
      //Code here
    } else if buttonPressed == "button two" {
        // Code here
    }
}

or popups with a single button like this:

Popups.SharedInstance.ShowPopup("Title goes here", message: "Message goes here.")
Dichromic answered 26/10, 2015 at 9:31 Comment(2)
Thanks. I submit some issue therePlaya
Hey @Dichromic Thanks so much man for sharing this solution with us! I got stuck with the closure thing and you just saved me!Youngs
D
5

Swift 3

The following is a simple example of how to create a simple alert with one button with Swift 3.

let alert = UIAlertController(title: "Title",
                              message: "Message",
                              preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default))
present(alert, animated: true)

In the above example the handle callback of the action has been omitted because the default behaviour of an alert view with one button is to disappear when the button is clicked.

Here is how to create another action, which could be added to the alert with "alert.addAction(action)". The different styles are .default, .destructive and .cancel.

let action = UIAlertAction(title: "Ok", style: .default) { action in
    // Handle when button is clicked    
}
Dendrology answered 28/9, 2016 at 12:52 Comment(0)
S
4

I got the following UIAlertView initialization code to compile without errors (I thing the last, varyadic part is tricky perhaps). But I had to make sure the class of self (which I am passing as the delegate) was adopting the UIAlertViewDelegate protocol for the compile errors to go away:

let alertView = UIAlertView(
                  title: "My Title",
                  message: "My Message",
                  delegate: self,
                  cancelButtonTitle: "Cancel",
                  otherButtonTitles: "OK"
                )

By the way, this is the error I was getting (as of Xcode 6.4):

Cannot find an initializer for type 'UIAlertView' that accepts an argument list of type '(title: String, message: String, delegate: MyViewController, cancelButtonTitle: String, otherButtonTitles: String)'

As others mentioned, you should migrate to UIAlertController if you can target iOS 8.x+. To support iOS 7, use the code above (iOS 6 is not supported by Swift).

Schoof answered 14/7, 2015 at 7:44 Comment(0)
L
4
 let alertController = UIAlertController(title: "Select Photo", message: "Select atleast one photo", preferredStyle: .alert)
    let action1 = UIAlertAction(title: "From Photo", style: .default) { (action) in
        print("Default is pressed.....")
    }
    let action2 = UIAlertAction(title: "Cancel", style: .cancel) { (action) in
        print("Cancel is pressed......")
    }
    let action3 = UIAlertAction(title: "Click new", style: .default) { (action) in
        print("Destructive is pressed....")

    }
    alertController.addAction(action1)
    alertController.addAction(action2)
    alertController.addAction(action3)
    self.present(alertController, animated: true, completion: nil)

}
Laritalariviere answered 8/3, 2018 at 9:28 Comment(0)
H
4

You can use this simple extension with n number of buttons and associated actions swift4 and above

extension UIViewController {
    func popupAlert(title: String?, message: String?, actionTitles:[String?], actions:[((UIAlertAction) -> Void)?]) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        for (index, title) in actionTitles.enumerated() {
            let action = UIAlertAction(title: title, style: .default, handler: actions[index])
            alert.addAction(action)
        }
        self.present(alert, animated: true, completion: nil)
    }
}

you can use it like ,

self.popupAlert(title: "Message", message: "your message", actionTitles: ["first","second","third"], actions:[
            {action1 in
                //action for first btn click
            },
            {action2 in
                //action for second btn click
            },
            {action3 in
                //action for third btn click
            }, nil]) 
Horacehoracio answered 15/3, 2019 at 10:14 Comment(2)
you please don't post duplicate answers. If you want edit your answer.Anticatalyst
Excellent answer. This is what I need. Thank you!Atomic
C
4

Or just do this

        let alert = UIAlertController(title: "Alert", message: "Saved Successfully", preferredStyle: UIAlertController.Style.alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil))
        self.present(alert, animated: true, completion: nil)
Creamery answered 13/8, 2020 at 20:15 Comment(0)
S
3

The reason it doesn't work because some value you passed to the function isn't correct. swift doesn't like Objective-C, you can put nil to arguments which are class type without any restriction(might be). Argument otherButtonTitles is defined as non-optional which its type do not have (?)at its end. so you must pass a concrete value to it.

Stook answered 28/6, 2014 at 8:49 Comment(0)
B
3
@IBAction func Alert(sender: UIButton) {

    var alertView:UIAlertView = UIAlertView()
    alertView.title = "Alert!"
    alertView.message = "Message"
    alertView.delegate = self
    alertView.addButtonWithTitle("OK")

    alertView.show()

}

Try this

Beeswax answered 13/10, 2014 at 22:55 Comment(0)
S
3

Use this code to display an alertview

  let alertController = UIAlertController(title: "Hello  Coders", message: "your alert message", preferredStyle: .Alert)
        let defaultAction = UIAlertAction(title: "Close Alert", style: .Default, handler: nil)
        alertController.addAction(defaultAction)

        presentViewController(alertController, animated: true, completion: nil)

Reference: Swift Show Alert using UIAlertController

Selenodont answered 10/10, 2016 at 2:47 Comment(0)
C
3

in xcode 9

let alert = UIAlertController(title: "Alert", message: "message", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
Creigh answered 5/10, 2017 at 6:34 Comment(0)
R
3

SWIFT 4 : Simply create a extension to UIViewController as follows:

extension  UIViewController {        
    func showSuccessAlert(withTitle title: String, andMessage message:String) {
        let alert = UIAlertController(title: title, message: message,
                                  preferredStyle: UIAlertController.Style.alert)
        alert.addAction(UIAlertAction(title: "OK".localized, style:
        UIAlertAction.Style.default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }
}

Now in your ViewController, directly call above function as if they are provided by UIViewController.

    yourViewController.showSuccessAlert(withTitle: 
      "YourTitle", andMessage: "YourCustomTitle")
Ratel answered 3/6, 2018 at 13:37 Comment(1)
Generally, answers are much more helpful if they include an explanation of what the code is intended to do, and why that solves the problem without introducing others. Thanks for improving the answer's reference value and making it more understandable!Sycee
S
2

try This. Put Bellow Code In Button.

let alert = UIAlertController(title: "Your_Title_Text", message: "Your_MSG", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Your_Text", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated:true, completion: nil)
Skimp answered 1/12, 2017 at 8:0 Comment(0)
G
2

// Custom Class For UIAlertView

//MARK:- MODULES
import Foundation
import UIKit

//MARK:- CLASS
class Alert  : NSObject{

static let shared = Alert()

var okAction : AlertSuccess?
typealias AlertSuccess = (()->())?
var alert: UIAlertController?

/** show */
public func show(title : String?, message : String?, viewController : UIViewController?, okAction : AlertSuccess = nil) {

    let version : NSString = UIDevice.current.systemVersion as NSString
    if  version.doubleValue >= 8 {
        alert = UIAlertController(title: title, message: message, preferredStyle:.alert)
        alert?.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action: UIAlertAction) in

            if let okAction = okAction {
                okAction()
            }
        }))
        viewController?.present(alert ?? UIAlertController(), animated:true, completion:nil);
    }
}

/** showWithCancelAndOk */
public func showWithCancelAndOk(title : String, okTitle : String, cancelTitle : String, message : String, viewController : UIViewController?, okAction : AlertSuccess = nil, cancelAction : AlertSuccess = nil) {
    let version:NSString = UIDevice.current.systemVersion as NSString;

    if  version.doubleValue >= 8 {
        alert = UIAlertController(title: title, message: message, preferredStyle:.alert)

        alert?.addAction(UIAlertAction(title: cancelTitle, style: .default, handler: { (action: UIAlertAction) in

            if let cancelAction = cancelAction {
                cancelAction()
            }
        }))
        alert?.addAction(UIAlertAction(title: okTitle, style: .default, handler: { (action: UIAlertAction) in

            if let okAction = okAction {
                okAction()
            }
        }))
        viewController?.present(alert!, animated:true, completion:nil);
    }
}

/** showWithTimer */
public func showWithTimer(message : String?, viewController : UIViewController?) {

    let version : NSString = UIDevice.current.systemVersion as NSString
    if  version.doubleValue >= 8 {
        alert = UIAlertController(title: "", message: message, preferredStyle:.alert)
        viewController?.present(alert ?? UIAlertController(), animated:true, completion:nil)
        let when = DispatchTime.now() + 1
        DispatchQueue.main.asyncAfter(deadline: when){
            self.alert?.dismiss(animated: true, completion: nil)
        }
    }
}
}

Use:-

Alert.shared.show(title: "No Internet Connection", message: "The internet connection appers to be offline.", viewController: self) //without ok action

Alert.shared.show(title: "No Internet Connection", message: "The internet connection appers to be offline.", viewController: self, okAction: {
                            //ok action
                        }) // with ok action

Alert.shared.show(title: "No Internet Connection", message: "The internet connection appers to be offline.", viewController: self, okAction: {
                            //ok action 
}, cancelAction: {
 //cancel action
}) //with cancel and ok action

Alert.shared.showWithTimer(message : "This is an alert with timer", viewController : self) //with timer
Goblin answered 28/2, 2018 at 13:24 Comment(0)
C
1

Here is a funny example in Swift:

private func presentRandomJoke() {
  if let randomJoke: String = jokesController.randomJoke() {
    let alertController: UIAlertController = UIAlertController(title:nil, message:randomJoke, preferredStyle: UIAlertControllerStyle.Alert)
    alertController.addAction(UIAlertAction(title:"Done", style:UIAlertActionStyle.Default, handler:nil))
    presentViewController(alertController, animated:true, completion:nil)
  }
}
Cutinize answered 25/4, 2015 at 6:51 Comment(0)
R
1

Here is a pretty simple function of AlertView in Swift :

class func globalAlertYesNo(msg: String) {
        let alertView = UNAlertView(title: "Title", message: msg)

        alertView.messageAlignment = NSTextAlignment.Center
        alertView.buttonAlignment  = UNButtonAlignment.Horizontal

        alertView.addButton("Yes", action: {

            print("Yes action")

        })

        alertView.addButton("No", action: {

            print("No action")

        })

        alertView.show()

    }

You have to pass message as a String where you use this function.

Ransdell answered 15/6, 2016 at 9:4 Comment(0)
H
1

The Old Way: UIAlertView

let alertView = UIAlertView(title: "Default Style", message: "A standard alert.", delegate: self, cancelButtonTitle: "Cancel", otherButtonTitles: "OK")
alertView.alertViewStyle = .Default
alertView.show()

// MARK: UIAlertViewDelegate

 func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) {
 switch buttonIndex {

    // ...
   }
  }

The New Way: UIAlertController

let alertController = UIAlertController(title: "Default Style", message: "A standard alert.", preferredStyle: .Alert)

let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
// ...
 }
 alertController.addAction(cancelAction)

 let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
// ...
 }
 alertController.addAction(OKAction)
 self.presentViewController(alertController, animated: true) {
 // ...
}
Hydrophilic answered 4/7, 2016 at 8:43 Comment(0)
F
1

on IOS 9, you can do this

let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
Foliaceous answered 28/12, 2017 at 10:46 Comment(0)
E
1
  // UIAlertView is deprecated. Use UIAlertController 
  // title = title of the alert view.
  // message = Alert message you want to show.
  // By tap on "OK" , Alert view will dismiss.

 UIAlertView(title: "Alert", message: "Enter Message here.", delegate: nil, cancelButtonTitle: "OK").show()
Eterne answered 4/5, 2018 at 7:3 Comment(2)
Can you please add an explanation to the code you posted? As it is now, your answer does not really qualify as a good answer by SO rules.Chemist
alert view has changed now in swift 4.use alert controllerAgriculturist
I
1

Below is the reusable code for alert view and action sheet, Just write one line to show alert anywhere in application

class AlertView{

    static func show(title:String? = nil,message:String?,preferredStyle: UIAlertControllerStyle = .alert,buttons:[String] = ["Ok"],completionHandler:@escaping (String)->Void){
        let alert = UIAlertController(title: title, message: message, preferredStyle: preferredStyle)

        for button in buttons{

            var style = UIAlertActionStyle.default
            let buttonText = button.lowercased().replacingOccurrences(of: " ", with: "")
            if buttonText == "cancel"{
                style = .cancel
            }
            let action = UIAlertAction(title: button, style: style) { (_) in
                completionHandler(button)
            }
            alert.addAction(action)
        }

        DispatchQueue.main.async {
            if let app = UIApplication.shared.delegate as? AppDelegate, let rootViewController = app.window?.rootViewController {
                rootViewController.present(alert, animated: true, completion: nil)
            }

        }
    }
}

Usage :

class ViewController: UIViewController {

    override func viewWillAppear(_ animated: Bool) {
        AlertView.show(title: "Alert", message: "Are you sure ?", preferredStyle: .alert, buttons: ["Yes","No"]) { (button) in
            print(button)
        }
    }

}
Idleman answered 15/8, 2018 at 11:1 Comment(0)
H
1

SwiftUI on Swift 5.x and Xcode 11.x

import SwiftUI

struct ContentView: View {

    @State private var isShowingAlert = false

    var body: some View {
        VStack {
            Button("A Button") {

                self.isShowingAlert.toggle()
            }
            .alert(isPresented: $isShowingAlert) { () -> Alert in
                Alert(
                    title: Text("Alert"),
                    message: Text("This is an alert"),
                    dismissButton:
                        .default(
                            Text("OK"),
                            action: {
                                print("Dismissing alert")
                            }
                        )
                )
            }

        }
        .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Haemachrome answered 8/10, 2019 at 17:28 Comment(2)
Dude this is swift ui that's not what's askedClinkscales
Yes, but since we use StackOverflow as a documentation resource, I thought it could be useful to anyone looking for how to present notifications using SwiftUI. I remember having a hard time finding the answer to that, and thought I could contribute posting this here. I view the question like "how to present an alert in a Swift application" rather than "how to present UIAlert using exclusively UIKit".Haemachrome
D
1

For above 13.0 version Using SceneDelegate

For All Kind of Classes

static func showWindowAlert(alertMessage: String, inVC:UIViewController) {
        DispatchQueue.main.async(execute: {
            guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
                let sceneDelegate = windowScene.delegate as? SceneDelegate
              else {
                return
              }
            sceneDelegate.window?.rootViewController = inVC
            sceneDelegate.window?.windowLevel = UIWindow.Level.alert + 1
        
            let alert2 = UIAlertController(title: App_Name, message: alertMessage, preferredStyle: .alert)
            let defaultAction2 = UIAlertAction(title: "OK", style: .default, handler: { action in
            })
            alert2.addAction(defaultAction2)
        
            sceneDelegate.window?.makeKeyAndVisible()
        
            sceneDelegate.window?.rootViewController?.present(alert2, animated: true, completion: nil)
        })
    }
Diplomatist answered 4/12, 2021 at 8:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.