Create Alert Function in All View Controllers - Swift

create alert function in all view controllers - swift

What I would do is to create a 'generic' view controller that do the job and than inherit from it:

1. If you want to display alert each time view did appear:

class GenericViewController: UIViewController {

// MARK: - View lifecycle -

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let notification = self.shouldDisplayAlertNotification() {
self.showNotification(notification)
}
}

// MARK: - Internal methods -

func shouldDisplayAlertNotification() -> AlertNotification? {
return nil
}

// MARK: - Private methods -

private func showNotification(_ alertNotification: AlertNotification) {
}

}

class MyController: GenericViewController {

override func shouldDisplayAlertNotification() -> AlertNotification? {
return AlertNotification(title: "Title", message: "Message")
}

}

Where AlertNotification is your custom model class:

class AlertNotification {
var title: String
var message: String

init(title: String, message: String) {
self.title = title
self.message = message
}
}

In this way, only VC that overrides shouldDisplayAlertNotificationwill display alert.

2. If you want to display alert on 'demand':

As suggested, extend UIViewController

extension UIViewController {
func showNotification(title: String, message: String) {
}
}

How to create a reusable alert view used across different view controllers?

You need alert action to performing ok action.

You can modify your code by this

Here are the helper functions.

struct AlertView {
public static func showAlertBox(title: String, message: String, handler: ((UIAlertAction)->Void)?) -> UIAlertController {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: handler))
return alert
}
}

extension UIAlertController {
func present(on viewController: UIViewController, completion: (() -> Void)? = nil) {
viewController.present(self, animated: true, completion: completion)
}
}

Usage

class ViewController: UIViewController {

@IBAction func submitPressed(_ sender: Any) {
AlertView.showAlertBox(title: "Hours Added", message: "Hours have been updated") { [weak self] action in
// Okay action code
}.present(on: self) { [weak self] in
self?.dismiss(animated: true, completion: nil)
self?.timeSubmitted = true
self?.performSegue(withIdentifier: "unwindToMyHours", sender: nil)
}
}
}
Note: self is dismissing so might be your alert is not presenting. You can present your alert on top most view controller. see this

How would I create a UIAlertView in Swift?

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)

create a display alert function globally and call it from any view controller

I run your code and it working fine. I thing you would pass self in vc.

 self.displayalert(title: "Title", message: "Some Message", vc: self)

You can also make an extension of UIViewController-

   extension UIViewController {
// Your Function...
}

Now You can globally access this function from any view controller, Just by typing-

    self.displayalert(title: "Title", message: "Some Message", vc: self)

How to show alert in all controllers without repeating the code?

Developing on Swift you should know about protocols which can solve your problem easily. You can create a new protocol MyAlert and make default implementation for UIViewController class. And then just inherit your MyAlert protocol in view controller, where you need it, and call the function!

protocol MyAlert {
func runMyAlert()
}

extension MyAlert where Self: UIViewController {
func runMyAlert() {
let alert = UIAlertController(title: title, message: "message", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "buttonTitle", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}

So you can implement and call it like that:

class MyViewController: UIViewController, MyAlert {
override func viewDidLoad() {
runMyAlert() // for test
}
}

UPD:

code for your case:

protocol MyAlert {
func runMyAlert()
}

extension MyAlert where Self: UIViewController {
func runMyAlert() {
let alert = UIAlertController(title: title, message: "message", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "buttonTitle", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}

class OpenChatsTableViewController: UITableViewController, MyAlert, OneRosterDelegate, BuddyRequestProtocol {
override func viewDidLoad() {
runMyAlert()
}
}

How to create an alert in your Data Model, and call it in your ViewController as a parameter

You are passing a different view controller than the one you are calling the function from. It is nil because that view controller is not instantiated.

Do this instead:

addAlert(viewController: self)

How to create uialertcontroller in global swift

self.window would mean that there's a window object in this class, and it's not the case.

You would need to use your let window : UIWindow? with window?.presentViewController(alert, animated: true, completion: nil), but this won't help, since this window does not actually represent any existing window, and it's not a view controller anyway.

So I suggest you pass the actual view controller you'll be using to the method:

static func showAlertMessage(vc: UIViewController, titleStr:String, messageStr:String) -> Void {
let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert);
vc.presentViewController(alert, animated: true, completion: nil)
}

and you call it from a class where a UIViewController object is available.

Swift calling a view controller from a different controller or calling an alert from different controller

So as per my underStanding, You are trying to show an alert during the AppDelegate.

But it is not possible to show there, basically what will happen is that AppDelegate will be called when the app starts , after that the View controller which is first in the stack will be called.

If you have made any Condition in AppDelegate and in that case want to show alert there,

You can use

func showAlertAppDelegate(title : String,message : String,buttonTitle : String,window: UIWindow){ 
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: buttonTitle, style: UIAlertActionStyle.default, handler: nil))
window.rootViewController?.present(alert, animated: true, completion: nil)
}

And use it like:

showAlertAppDelegate(title: "Alert!", message: "Message", buttonTitle: "Ok", window: self.window!)

Note:- This alert will be shown on the first VC that will be loaded after the App delegate is called.

Displaying an alert on a new View Controller

In the viewDidLoad() method of the new controller, create a new UIAlertController and display it like the following

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) {
// ...
}

Note that this example was taken from the NSHipster website which offers nice articles about iOS. You can find the article about UIAlertController here. They also explain other stuff you can do with that class, like display an Action Sheet for example.

Swift Displaying Alerts best practices

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)
}
}


Related Topics



Leave a reply



Submit