How to create uialertcontroller in global swift

2020-02-08 09:51发布

问题:

I'm trying to create uialertcontroller in Config.swift file as follow.

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

problem is I've found problem in self.window!.

Type 'Config' has no member 'window'

Please let me know how to solve that issue.

回答1:

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.



回答2:

swift

Here's what I used, this is the same as @penatheboss answered, just add the ability of adding actions and handlers.

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

Just make sure actionTitles and actions array the same count. Pass nil if you don't need any action handler closure.

self.popupAlert(title: "Title", message: " Oops, xxxx ", actionTitles: ["Option1","Option2","Option3"], actions:[{action1 in

},{action2 in

}, nil])

Objective C:

Add the category for UIViewController

UIViewController+PopAlert.h

#import <UIKit/UIKit.h>

@interface UIViewController (UIViewControllerCategory)
- (void) popAlertWithTitle: (NSString*) title message: (NSString*) message actionTitles:(NSArray *) actionTitles actions:(NSArray*)actions;
@end

UIViewController+PopAlert.m

#import "UIViewController+PopAlert.h"

@implementation UIViewController (UIViewControllerCategory)
- (void) popAlertWithTitle: (NSString*) title message: (NSString*) message actionTitles:(NSArray *) actionTitles actions:(NSArray*)actions {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    [actionTitles enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        UIAlertAction *action = [UIAlertAction actionWithTitle:obj style:UIAlertActionStyleDefault handler:actions[idx]];
        [alert addAction:action];
    }];
    [self presentViewController:alert animated:YES completion:nil];
}
@end

Usage:

#import UIViewController+PopAlert.h

...

[super viewDidDisappear:animated];
    NSArray *actions = @[^(){NSLog(@"I am action1");}, ^(){NSLog(@"I am action2");}];
    [self popAlertWithTitle:@"I am title" message:@"good" actionTitles:@[@"good1", @"good2"] actions:actions];


回答3:

I suggest creating an extension:

extension UIViewController {
    func showAlertMessage(titleStr:String, messageStr:String) {
        let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert)
       self.presentViewController(alert, animated: true, completion: nil)
    }
}


回答4:

You can try this, please add below code in AppDelegate.swift file.

 static func showAlertView(vc : UIViewController, titleString : String , messageString: String) ->()
    {
        let alertView = UIAlertController(title: titleString, message: messageString, preferredStyle: .alert)

        let alertAction = UIAlertAction(title: "ok", style: .cancel) { (alert) in
            vc.dismiss(animated: true, completion: nil)
        }
        alertView.addAction(alertAction)
        vc.present(alertView, animated: true, completion: nil)

    }

and call showAlertView method from any viewcontroller

AppDelegate.showAlertView(vc: self, titleString: "testTitle", messageString: "test msg")


回答5:

I created a alerMessage class .I can call any where in my application

//Common Alert Message Class 

class AlertMessage {

internal static var alertMessageController:UIAlertController!

internal static func disPlayAlertMessage(titleMessage:String, alertMsg:String){


    AlertMessage.alertMessageController = UIAlertController(title: titleMessage, message:
        alertMsg, preferredStyle: UIAlertControllerStyle.Alert)

    AlertMessage.alertMessageController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default,handler: nil))
    if let controller = UIApplication.sharedApplication().keyWindow?.rootViewController?.presentedViewController {
        controller.presentViewController(AlertMessage.alertMessageController, animated: true, completion: nil)
    }
    else{
        UIApplication.sharedApplication().delegate?.window!!.rootViewController?.presentViewController(AlertMessage.alertMessageController, animated: true, completion: nil)
    }

    return

 }
}


回答6:

Please refer the below GIT Example

https://github.com/amilaim/CommonAlertView

//  ViewController.swift
//  CommonAlertView
//
//  Created by Amila Munasinghe on 4/25/17.
//  Copyright © 2017 Developer Insight. All rights reserved.
//
import UIKit

class ViewController: UIViewController,AlertViewControllerDelegate {

@IBOutlet weak var AlertViewResultTextOutlet: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

@IBAction func ShowAlertAction(_ sender: Any) {

    let alert = AlertViewController.sharedInstance
    alert.delegate = self
    alert.SubmitAlertView(viewController: self,title: "Developer Insight", message: "Please enter any text value")

}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


func SubmitAlertViewResult(textValue : String) {

    AlertViewResultTextOutlet.text = textValue

 } 
}

Common UIAlertViewController Implementation

import UIKit

protocol AlertViewControllerDelegate {
func SubmitAlertViewResult(textValue : String)
 }

class AlertViewController {

static let sharedInstance = AlertViewController()

private init(){}

var delegate : AlertViewControllerDelegate?

func SubmitAlertView(viewController : UIViewController,title : String, message : String){

    let alert = UIAlertController(title: title,
                                  message: message,
                                  preferredStyle: .alert)

    // Submit button
    let submitAction = UIAlertAction(title: "Submit", style: .default, handler: { (action) -> Void in
        // Get 1st TextField's text
        let textField = alert.textFields![0]

        if(textField.text != "")
        {
            self.delegate?.SubmitAlertViewResult(textValue: textField.text!)
        }

    })

    // Cancel button
    let cancel = UIAlertAction(title: "Cancel", style: .destructive, handler: { (action) -> Void in })


    // Add 1 textField and cutomize it
    alert.addTextField { (textField: UITextField) in
        textField.keyboardAppearance = .dark
        textField.keyboardType = .default
        textField.autocorrectionType = .default
        textField.placeholder = "enter any text value"
        textField.clearButtonMode = .whileEditing

    }

    // Add action buttons and present the Alert
    alert.addAction(submitAction)
    alert.addAction(cancel)
    viewController.present(alert, animated: true, completion: nil)

 }

}


回答7:

What I'm using based on the solution by @William Hu:

func popup(caller:UIViewController, style:UIAlertControllerStyle? = UIAlertControllerStyle.alert,
        title:String, message:String, buttonTexts:[String], buttonStyles:([UIAlertActionStyle?])? = nil,
        handlers:[((UIAlertAction) -> Void)?], animated:Bool? = nil, completion: (() -> Void)? = nil) {
    let alert = UIAlertController(title: title, message: message, preferredStyle: style!)
    for i in 0..<buttonTexts.count {
        alert.addAction(UIAlertAction(title: buttonTexts[i],
            style: (buttonStyles == nil || i >= buttonStyles!.count || buttonStyles![i] == nil ?
                UIAlertActionStyle.default : buttonStyles![i]!),
            handler: (i >= handlers.count || handlers[i] == nil ? nil : handlers[i]!)))
    }
    caller.present(alert, animated: animated != nil ? animated! : true, completion: completion)
}
  1. Single function gives Alert by default and can optionally be used for ActionSheet.
  2. Arrays buttonTexts, buttonStyles and handlers can be of unequal sizes as per requirement.
  3. Actions can be styled.
  4. Animated can be specified.
  5. Optional block can be specified to be executed when presentation finishes.

Usage:

popup(caller: self, style: UIAlertControllerStyle.alert,
        title: "Title", message: "Message",
        buttonTexts: ["Destructive", "Cancel", "OK"],
        buttonStyles: [UIAlertActionStyle.destructive, UIAlertActionStyle.cancel],
        handlers: [nil], animated: false)


回答8:

You can use my Utility class created for Show Alert in Swift4. Its super easy to use just by writing single line of code:

Show Simple Alert

@IBAction func showDefaultAlert(_ sender: Any) {

  Alert.showAlert(title:"Alert", message:"Default Alert")

}

Demo code link: https://github.com/smindia1988/EasyAlertInSwift4



回答9:

I am suggest you write this code, but if you really need, try this:

static func showAlertMessage(titleStr:String, messageStr:String) -> Void {
    let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert);
    if let viewController = UIApplication.sharedApplication().windows.first?.rootViewController as UIViewController? {
        viewController.presentViewController(alert, animated: true, completion: nil)
    }
}

At least it won't break down.

@Eric D better answer.



回答10:

If you want to present from AppDelegate windows you can use like this

UIApplication.sharedApplication().delegate?.window.rootViewController?.presentViewController(vc, animated: true, completion: nil)


回答11:

This is also the way you can present on top of the View Controller available.

UIApplication.topViewController()?.present(alertViewController!, animated: true, completion: nil)