How to show an alert from another class in Swift?

烂漫一生 提交于 2019-12-09 04:08:44

问题


I have a main class, AddFriendsController, that runs the following line of code:

ErrorReporting.showMessage("Error", msg: "Could not add student to storage.")

I then have this ErrorReporting.swift file:

import Foundation

class ErrorReporting {
    func showMessage(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.presentViewController(alert, animated: true, completion: nil)
    }
}

Obviously, self wouldn't work here, and is giving me an error. How can I refer to the currently open view controller (i.e. AddFriendsController in this circumstance), as I am wishing to use this same method in many different swift files?

Thanks.


回答1:


You can create extension method for UIApplication (for example) which will return your topViewController:

extension UIApplication {

    static func topViewController(base: UIViewController? = UIApplication.sharedApplication().delegate?.window??.rootViewController) -> UIViewController? {
        if let nav = base as? UINavigationController {
            return topViewController(nav.visibleViewController)
        }
        if let tab = base as? UITabBarController, selected = tab.selectedViewController {
            return topViewController(selected)
        }
        if let presented = base?.presentedViewController {
            return topViewController(presented)
        }

        return base
    }
}

And then your class will look like this:

class ErrorReporting {

    static func showMessage(title: String, msg: String) {
        let alert = UIAlertController(title: title, message: msg, preferredStyle: UIAlertControllerStyle.Alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
        UIApplication.topViewController()?.presentViewController(alert, animated: true, completion: nil)
    }
}

Method need to be static to be able to call it as ErrorReporting.showMessage.




回答2:


Actually, in my opinion the view controller presenting operation should be done on the UIViewController instance, not in a model class.

A simple workaround for it is to pass the UIViewController instance as a parameter

class ErrorReporting {
    func showMessage(title: String, msg: String, `on` controller: UIViewController) {
        let alert = UIAlertController(title: title, message: msg, preferredStyle: UIAlertControllerStyle.Alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
        controller.presentViewController(alert, animated: true, completion: nil)
    }
}

And call it like below

ErrorReporting.showMessage("Error", msg: "Could not add student to storage.", on: self)



回答3:


Swift 3 version of Maksym Musiienko's answer would be the following:

extension UIApplication {

    static func topViewController(base: UIViewController? = UIApplication.shared.delegate?.window??.rootViewController) -> UIViewController? {

        if let nav = base as? UINavigationController {
            return topViewController(base: nav.visibleViewController)
        }

        if let tab = base as? UITabBarController, let selected = tab.selectedViewController {
            return topViewController(base: selected)
        }

        if let presented = base?.presentedViewController {
            return topViewController(base: presented)
        }

        return base
    }
}


来源:https://stackoverflow.com/questions/40015171/how-to-show-an-alert-from-another-class-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!