How to implement a YesNo box as a ViewController method? - ios

I would like to add a method to my ViewController that shows a message with text as an alert with a Yes and a No button. The result should be of type Bool (Yes/No).
What I have tried is the following:
func YesNoBox(msg: String) -> Bool
{
var retVal = false
let alert = UIAlertController(title: "", message: msg, preferredStyle: .alert)
let action_yes = UIAlertAction(title: "Yes", style: .default, handler:
{ _ in NSLog("The \"Yes\" alert occured."); retVal = true })
let action_no = UIAlertAction(title: "No", style: .cancel, handler:
{ _ in NSLog("The \"No\" alert occured."); retVal = false })
alert.addAction(action_yes)
alert.addAction(action_no)
self.present(alert, animated: true, completion: nil)
return retVal
}
However, the value of retVal is always false. If I was in C/C++, I guess I could resolve this issue with a pointer, but this is Swift (and I am pretty new to this).
Any idea anyone how I could get this working?
EDIT: The problem that I have is the following. On a ViewController I have a TextField. When I tap on the text field, the app should ask the user whether they want to paste the text from the clipboard. If yes, paste, otherwise give the TextField the focus (i.e. let the cursor blink in it). I tried to do this with 'textFieldShouldBeginEditing' and in this method I display the YesNoBox. The problem is that the TextField never gets the focus after the YesNoBox is closed. And when I use 'becomeFirstResponder()' after the Box call, the app freezes. I don't know what to do?

Use a completion
func yesNoBox(msg: String,completion:#escaping(Bool) -> ())
{
let alert = UIAlertController(title: "", message: msg, preferredStyle: .alert)
let action_yes = UIAlertAction(title: "Yes", style: .default, handler:
{ _ in
NSLog("The \"Yes\" alert occured.");
completion(true)
})
let action_no = UIAlertAction(title: "No", style: .cancel, handler:
{ _ in
NSLog("The \"No\" alert occured.");
completion(false)
})
alert.addAction(action_yes)
alert.addAction(action_no)
self.present(alert, animated: true, completion: nil)
}
call
yesNoBox(msg:"someMessage") { yes in
if yes {
// do yes action
}
else {
// do no action
}
}
2 Callbacks:
This function has 2 completions ( imagine we have a function that uploads an image and notifies the progress with a completion and another 1 to say done )
func uploadImage(data: Data,progress:#escaping(Float) -> (),completion:#escaping(Bool) -> ()) {
// implementation here
}
To call
self.uploadImage(someData) { progress in
print(progress)
}) { done in
print(done)
}

This can be achieved with completion handlers.
func showAlertWithOptions(title: String, message: String, completionHandler: #escaping (Bool) -> Void) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
let action_yes = UIAlertAction(title: "Yes", style: .default, handler: { _ in
completionHandler(true)
})
let action_no = UIAlertAction(title: "No", style: .cancel, handler: { _ in
completionHandler(false)
})
alert.addAction(action_yes)
alert.addAction(action_no)
self.present(alert, animated: true, completion: nil)
}
Now call the function and add any other functions or actions that you want to perform depending on the action selected.
showAlertWithOptions(title: "Any title", message: "Any message") { success in
if success {
NSLog("The \"Yes\" alert occured.")
} else {
NSLog("The \"No\" alert occured.")
}
}

Related

iOS - UIAlertController actions not triggering handler

I'm extremely new to iOS. I'm trying to show a dialog to the user to get some input, but the actions are never triggered. I've been searching on the net for hours and no answer seem to work for me.
Here's the function I'm trying to use to show the dialog:
private func showAmountDialog(type: String, onComplete: #escaping (Double) -> Void) {
let alert = UIAlertController(title: "Enter an amount", message: nil, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: LzStrings.Common_Cancel, style: .cancel, handler: nil))
alert.addTextField(configurationHandler: { textField in
textField.placeholder = "0.00 \(type)"
textField.keyboardType = .decimalPad
})
alert.addAction(UIAlertAction(title: LzStrings.Common_OK, style: .default) { (UIAlertAction) in
if let input = alert.textFields?.first?.text, let amount = Double(input) {
print("Your amount: \(amount)")
}
})
self.present(alert, animated: true)
}
self here is my ViewController which has a parent of UIViewController type and several other protocols.
What I might be doing wrong?
EDIT: The way I knew it isn't executing is using break-points and not by relying on print("...")
Also, since I added the TextField right before adding the action, the nullability check is useless and the textFields.first is never nil, so in both cases, a break-point should be triggered or the print("...") should be executed, which neither of them is happening.
EDIT 2: Since the if statement can do a little distraction, I edited my code this way and tested again:
alert.addAction(UIAlertAction(title: LzStrings.Common_OK, style: .default) { (UIAlertAction) in
if let input = alert.textFields?.first {
if let amount = Double(input.text ?? "") {
print("Your amount: \(amount)")
} else {
print("Can't cast this string to double")
}
} else {
print("Text field is null")
}
})
Still, no feedback from the dialog.
PS: Even the Cancel button doesn't work.
EDIT 3: My dismiss function is overridden in the super class, but it passes completion closure normally:
override open func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
if let navigationController = self.navigationController as? NavigationController {
navigationController.dismiss(animated: flag, completion: completion)
} else {
super.dismiss(animated: flag, completion: completion)
}
}
After having a conversation with one of my colleagues, we found out that to show standard UIAlertController we must use this:
self.view.window!.rootViewController?.present(alert, animated: true, completion: nil)
Instead of this
self.present(alert, animated: true, completion: nil)
It fixed my issue. I hope someone will find this helpful.
Another option is to use an extention for ViewController:
extension UIViewController {
//Show a basic alert
func showAlert(alertText : String, alertMessage : String) {
let alert = UIAlertController(title: alertText, message: alertMessage, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Got it", style: UIAlertActionStyle.default, handler: nil))
//Add more actions as you see fit
self.present(alert, animated: true, completion: nil)
}
}

How to show alert after keyboard has been shown in UITextView textViewDidBeginEditing

Inside textViewDidBeginEditing I'm showing alert using UIAlertController. Alert is shown prior to the keyboard (on simulator).
How do I show keyboard before alert pops up?
func textViewDidBeginEditing(_ textView: UITextView) {
if self.balance <= 0 {
let alert = UIAlertController(title: "Balance Low", message: "Your balance is low.", preferredStyle: UIAlertControllerStyle.alert)
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel) { (cancel) in
}
let okAction = UIAlertAction(title: "Buy", style: UIAlertActionStyle.default) { (action) in
self.segueToBuy()
}
alert.addAction(cancelAction)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}
}
Please use DispatchQueue.main.asyncAfter to show the alert after certain delay, whenever user typed the text in UITextView.
func asyncAfter(deadline: DispatchTime, qos: DispatchQoS = default, flags: DispatchWorkItemFlags = default, execute work: #escaping #convention(block) () -> Void)
Delcare private instance variable which is used to show alert, locally.
var showAlert = true
Try the code shown below in textViewDidBeginEditing:
func textViewDidBeginEditing(_ textView: UITextView) {
if self.showAlert && self.balance <= 0 {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
textView.endEditing(true)
let alert = UIAlertController(title: "Balance Low", message: "Your balance is low.", preferredStyle: UIAlertController.Style.alert)
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel) { (cancel) in
self.showAlert = false
textView.becomeFirstResponder()
}
let okAction = UIAlertAction(title: "Buy", style: UIAlertAction.Style.default) { (action) in
textView.endEditing(true)
self.segueToBuy()
}
alert.addAction(cancelAction)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}
}
}

UIViewController and inheritance

I have multiple view controllers in my application. And in each of them I have to show alerts based on some conditions. Instead of adding alert controllers in each of them, I tried using inheritance as follows.
UIExtension.swift
class UIExtension: UIViewController {
func prepareAlert(title: String, message: String) -> UIAlertController {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
return alert
}
}
FirstViewController.swift
class FirstViewController: UIExtension {
//somewhere inside used the following
present(prepareAlert(title: "Error Validation", message: "invalid fields"), animated: true, completion: nil)
}
Similarly, used UIExtension in other viewcontrollers to show alerts. Is this way recommended?
For something like this, you are better off adding your prepareAlert method to a UIViewController extension. No subclassing required.
extension UIViewController {
func prepareAlert(title: String, message: String) -> UIAlertController {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
return alert
}
}
Then your view controller:
class FirstViewController: UIViewController {
//somewhere inside used the following
present(prepareAlert(title: "Error Validation", message: "invalid fields"), animated: true, completion: nil)
}
This allows you to use prepareAlert from any view controller include UITableViewController, UICollectionViewController, etc.
The approach is technically correct, although if you consider extending all UIViewController instances, regardless of any conditions, then it's more handy to extend it directly:
extension UIViewController {
func prepareAlert(title: String, message: String) -> UIAlertController {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
return alert
}
}
rmaddy was faster. But I decided not to delete the answer, but add another idea.
Another approach is to use protocol as a wrapper for certain functionality, and this is also widely used.
Say, you have a protocol, associated with some functionality, like generating alert, in this case:
protocol Alertable {} // or whatever else name
extension Alertable {
func prepareAlert(title: String, message: String) -> UIAlertController {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
return alert
}
}
Then, whenever you want certain UIViewController instance (or any other class, you get the idea) to be associated with this functionality, simply do:
class FirstViewController: UIViewController, Alertable {
// Now you can do the same:
present(prepareAlert(title: "Error Validation", message: "invalid fields"), animated: true, completion: nil)
}
To sum up, making up a protocol and extending it, and then associating certain classes with it - to expose that functionality - is a very handy and useful practice. In particular, this is a good way to encapsulate some functionality, for example, if you don't mean global/class-wide access to it.
Some extension method I am sharing with you that is used frequently in most application you can use it in any where of UIViewController class and enjoy :)
extension UIViewController {
let kAPPNAME = "Your App name"
func showOkAlert(_ msg: String) {
let alert = UIAlertController(title:
kAPPNAME, message: msg, preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(okAction)
present(alert, animated: true, completion: nil)
}
func showOkAlertWithHandler(_ msg: String,handler: #escaping ()->Void){
let alert = UIAlertController(title: kAPPNAME, message: msg, preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default) { (type) -> Void in
handler()
}
alert.addAction(okAction)
present(alert, animated: true, completion: nil)
}
func showAlertWithActions(_ msg: String,titles:[String], handler:#escaping (_ clickedIndex: Int) -> Void) {
let alert = UIAlertController(title: kAPPNAME, message: msg, preferredStyle: .alert)
for title in titles {
let action = UIAlertAction(title: title, style: .default, handler: { (alertAction) in
//Call back fall when user clicked
let index = titles.index(of: alertAction.title!)
if index != nil {
handler(index!+1)
}
else {
handler(0)
}
})
alert.addAction(action)
}
present(alert, animated: true, completion: nil)
}
func showOkCancelAlertWithAction(_ msg: String, handler:#escaping (_ isOkAction: Bool) -> Void) {
let alert = UIAlertController(title: kAPPNAME, message: msg, preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default) { (action) -> Void in
return handler(true)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) -> Void in
return handler(false)
}
alert.addAction(cancelAction)
alert.addAction(okAction)
present(alert, animated: true, completion: nil)
}
}
USES
class FirstViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//Only Info
self.showOkAlert("Hello")
//Info with Okay button
self.showOkAlertWithHandler("Hello Again") {
print("Tap to Okay")
}
//Show alert with Okay and cancel
self.showOkCancelAlertWithAction("Hello with Cancel") { (isOk) in
if isOk {
print("Okay")
}
else {
print("Cancel")
}
}
//Show alert with actions
self.showAlertWithActions("Hello with action", titles: ["Allow","Don't Allow", "Cancel"]) { (tapIndex) in
if tapIndex == 1 {
print("Allow")
}
}
}
}

Using UIAlertView to Cancel a Touch

I am building a game.
This game has a UITableViewController which serves as a Settings & Options feature.
One of the options that you can select is to switch the opponent from pass and play to an AI (or the other way around).
What I'd like to do is use a UIAlertController to intercept the touch, check for a game in progress, and prompt the user to cancel the change or continue.
I have implemented the code to do this within the override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) function.
My code is as follows:
if indexPath.section == 1 {
// Here we need to detect a game in progress and ask for a confirmation before switching to another mode.
if getGameInProgress() == true {
// Display choice dialog
alert = UIAlertController (title: alertCaption, message: alertMessage, preferredStyle: .Alert)
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {(action: UIAlertAction) -> Void in
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
return
})
alert.addAction(cancelAction)
let ok: UIAlertAction = UIAlertAction(title: "Confirm", style: .Default, handler: {(action: UIAlertAction) -> Void in
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
// Do nothing, just let the touch method continue...
})
alert.addAction(ok)
self.presentViewController (alert, animated: true, completion: nil)
}
if indexPath.row == 0 {
// "Pass and Play"
setOpponentPreference("Pass and Play")
}
if indexPath.row == 1 {
// "Virtual Robert"
setOpponentPreference("Virtual Robert")
}
if indexPath.row == 2 {
// "Virtual Nathan"
setOpponentPreference("Virtual Nathan")
}
// No matter which difficulty selected:
gameboard.setDifficulty()
// Create a method to reset the game, but without fading out the menu screen (the current new game method takes you directly to the game. The player may not want that in this instance.)
}
The problem I am having is that the alert controller displays and waits for input, but it does not prevent the rest of the didSelectRowAtIndexPath function form continuing.
How do I receive the users input before handling the touch on the cell?
Hello All you need is put your code inside of your completion section for your "Confirm" option, your code will be execute only when user tap on "Confirm" button of your UIAlertViewController
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
// Do nothing, just let the touch method continue...
})
so your code must be
if indexPath.section == 1 {
// Here we need to detect a game in progress and ask for a confirmation before switching to another mode.
if getGameInProgress() == true {
// Display choice dialog
alert = UIAlertController (title: alertCaption, message: alertMessage, preferredStyle: .Alert)
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {(action: UIAlertAction) -> Void in
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
return
})
alert.addAction(cancelAction)
let ok: UIAlertAction = UIAlertAction(title: "Confirm", style: .Default, handler: {(action: UIAlertAction) -> Void in
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
if indexPath.row == 0 {
// "Pass and Play"
setOpponentPreference("Pass and Play")
}
if indexPath.row == 1 {
// "Virtual Robert"
setOpponentPreference("Virtual Robert")
}
if indexPath.row == 2 {
// "Virtual Nathan"
setOpponentPreference("Virtual Nathan")
}
// No matter which difficulty selected:
gameboard.setDifficulty()
// Create a method to reset the game, but without fading out the menu screen (the current new game method takes you directly to the game. The player may not want that in this instance.)
})
alert.addAction(ok)
self.presentViewController (alert, animated: true, completion: nil)
}
}
I hope this helps you, for me works great, regards
Sorry for the bad English. What I understand from you question is that you want to hold the program to continue execution till user select one of the button from UIAlertController.
for that you need to do is perform task inside the action of Ok button or Cancel button.
if getGameInProgress() == true {
// Display choice dialog
alert = UIAlertController (title: alertCaption, message: alertMessage, preferredStyle: .Alert)
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {(action: UIAlertAction) -> Void in
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
return
})
alert.addAction(cancelAction)
let ok: UIAlertAction = UIAlertAction(title: "Confirm", style: .Default, handler: {(action: UIAlertAction) -> Void in
//Do something in here like print
println("Confirm Button Pressed")
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
// Do nothing, just let the touch method continue...
})
alert.addAction(ok)
self.presentViewController (alert, animated: true, completion: nil)
}
hope it help.

Swift Displaying Alerts best practices

I have various controllers in my app that all require validation, and when validation fails, I want to display an alert with the errors. Is there some best practice/design pattern for doing this? I could simply create a static function in a Helper class like so:
static func displayAlert(message: String, buttonTitle: String, vc: UIViewController)
{
let alertController = UIAlertController(title: "", message: message, preferredStyle: .Alert)
let okAction = UIAlertAction(title: buttonTitle, style: .Default, handler: nil)
alertController.addAction(okAction)
vc.presentViewController(alertController, animated: true, completion: nil)
}
But then I need to pass the view controller..which seems like bad practice. I could shoot off a notification and observe it, but that seems like overkill. Am I overthinking this, or is there some more acceptable way to go about handling something like this?
I ended up creating an extension for UIViewController and creating the alert function there:
extension UIViewController {
func alert(message: String, title: String = "") {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(OKAction)
self.present(alertController, animated: true, completion: nil)
}
}
Swift 4
I wanted this same functionality for myself, so I made a full extension. To use it, create a new swift file in your project and name it whatever you'd like. Place the following code inside:
import UIKit
extension UIViewController {
func presentAlertWithTitle(title: String, message: String, options: String..., completion: #escaping (Int) -> Void) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
for (index, option) in options.enumerated() {
alertController.addAction(UIAlertAction.init(title: option, style: .default, handler: { (action) in
completion(index)
}))
}
self.present(alertController, animated: true, completion: nil)
}
}
To use it (which so many people don't actually show, which can lead to confusion for a newbie like myself):
presentAlertWithTitle(title: "Test", message: "A message", options: "1", "2") { (option) in
print("option: \(option)")
switch(option) {
case 0:
print("option one")
break
case 1:
print("option two")
default:
break
}
}
As original answer from itstrueimryan at https://stackoverflow.com/a/30714429/6822183
Update for Swift 3:
extension UIViewController {
func alert(message: String, title: String = "") {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(OKAction)
self.present(alertController, animated: true, completion: nil)
}
}
I may have found a better answer to this problem, via an article by Krakendev: https://krakendev.io/blog/subclassing-can-suck-and-heres-why.
The idea is to use protocol-oriented programming to create a default implementation of an alert just for UIViewControllers:
protocol Alertable {
func issueAlert()
}
extension Alertable where Self: UIViewController {
func issueAlert() {
// alert code here
}
}
Now, just like that, every UIViewController that adheres to Alertable will have the issueAlert() method available to them without even having to define its own implementation.
And, of course, we can define parameters for the issueAlert function as well:
extension Alertable where Self: UIViewController {
func issueAlert(title: "Default Title", message: String = "Default Message") {
// alert code here
}
}
So our view controller can do either:
issueAlert()
or
issueAlert(title: "Error", message: "Something went wrong")
Two advantages to this approach that I can think of are that you know if a view controller has access to this method just by looking at the Alertable protocol in the class definition, and individual view controllers can override this method if they want to provide custom functionality. Of course, now you can also specify the Alertable contract as a method parameter.
Answer from Sigex is completely fine, except the int indices passing to trace the button clicks might not make sense because, caller needed to keep track with int value. In that case passing string arguments and comparing them in switch case in completion block makes more sense to me. I would rather use like,
import UIKit
extension UIViewController {
func presentAlertWithTitle(title: String, message: String, options: String..., completion: #escaping (String) -> Void) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
for (index, option) in options.enumerated() {
alertController.addAction(UIAlertAction.init(title: option, style: .default, handler: { (action) in
completion(options[index])
}))
}
self.present(alertController, animated: true, completion: nil)
}
}
And test with,
class TestViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
presentAlertWithTitle(title: "Test", message: "A sample message", options: "start", "stop", "cancel") { (option) in
print("option: \(option)")
switch(option) {
case "start":
print("start button pressed")
break
case "stop":
print("stop button pressed")
break
case "cancel":
print("cancel button pressed")
break
default:
break
}
}
}
}
Why not create a Utility function that returns the AlertView to the ViewController?
self.presentViewController(Utilities.createAlertController("errorMessage"), animated: true, completion: nil);
Updated for swift 3:
if you want to show the alert message to user used below simple lines of code;
// function defination:
func showMessageToUser(title: String, msg: String) {
let alert = UIAlertController(title: title, message: msg, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
//function call :
self.showMessageToUser(title: "Alert", msg: "your message to user")
// Enjoy coding..!
I used Sigex's extension in my code, however I have added a check, if options were used or not.
If no options are given in the call, then the Alert only shows "OK" and completes with returning option 0.
extension UIViewController {
func presentAlertWithTitle(title: String, message: String, options: String..., completion: #escaping (Int) -> Void) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
if options.count == 0 {
let OKAction = UIAlertAction(title: "OK", style: .default, handler: { (action) in
completion(0)
})
alertController.addAction(OKAction)
} else {
for (index, option) in options.enumerated() {
alertController.addAction(UIAlertAction.init(title: option, style: .default, handler: { (action) in
completion(index)
}))
}
}
self.present(alertController, animated: true, completion: nil)
}
}
Just omit the part , options: "1","2" then default alert is shown.
I love Sigex's extension, but I spiced it up a bit to add style on button depending on the title
func presentAlertWithOptions(title: String, message: String, options: String..., completion: #escaping (Int) -> Void) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
if options.count == 0 { //if there is no options, show a basic alert
let OKAction = UIAlertAction(title: "OK", style: .default, handler: { (action) in
completion(0)
})
alertController.addAction(OKAction)
} else { //alert with options
for (index, option) in options.enumerated() {
var alertStyle = UIAlertAction.Style.default
switch option { //check if we should style the buttons
case "Cancel": //cancel style
alertStyle = .cancel
case "Logout", "Discard Changes", "Discard", "Delete", "Remove": //destructive style
alertStyle = .destructive
default: break //keep as default
}
alertController.addAction(UIAlertAction(title: option, style: alertStyle, handler: { (action) in
completion(index)
}))
}
}
self.present(alertController, animated: true, completion: nil)
}
Swift 4.1
let alert = UIAlertController(title: "Atenção",message: "Mensagem Aqui",preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
self.present(alert, animated: true)

Resources