Will Will - 1 month ago 6
iOS Question

How to encapsulate an UIViewController (like UIAlertController) in Swift?

I have a ViewController in my Storyboard which works like an alert (with a title, a message, and two buttons).

I would like to encapsulate it to be able to use it anywhere in my code, like this :

let alert = CustomAlertViewController(title: "Test", message: "message de test.", view: self.view, delegate: self)
self.present(alert, animated: false, completion: nil)


My problem is that the IBOutlets are not initialised...

My CustomAlertViewController :

public protocol CustomAlertProtocol {
func alertAccepted()
}

class CustomAlertViewController: UIViewController {

var delegate :CustomAlertProtocol? = nil
var parentView :UIView?
var blurScreenshot :SABlurImageView?

var alertTitle :String? = nil
var alertMessage :String? = nil

@IBOutlet weak var oAlertView: UIView!
@IBOutlet weak var oAlertTitle: UILabel!
@IBOutlet weak var oAlertMessage: UILabel!


//MARK: - Main

public convenience init(title: String?, message: String?, view: UIView, delegate: CustomAlertProtocol) {
self.init()
self.alertTitle = title
self.alertMessage = message
self.delegate = delegate
self.parentView = view
}

override func viewDidLoad() {
oAlertTitle.text = self.alertTitle
oAlertMessage.text = self.alertMessage
}

@IBAction func onAcceptButtonPressed(_ sender: AnyObject) {
delegate?.alertAccepted()
}
}

Answer

Set the Custom Class property of your View Controller to CustomAlertViewController
and Storyboard ID to whatever you want - e.g. CustomAlertViewControllerIdentifier in the Identity Inspector of the InterfaceBuilder.

And then instantiate it like following:

let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())

guard let vc = storyboard.instantiateViewControllerWithIdentifier("CustomAlertViewControllerIdentifier") as? CustomAlertViewController else {
    return
}

edit:

You can then put that code in a class function like:

extension CustomAlertViewController {
    class func instantiateFromStoryboard(title: String?, message: String?, view: UIView, delegate: CustomAlertProtocol) -> CustomAlertViewController {
        let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
        let vc = storyboard.instantiateViewControllerWithIdentifier("CustomAlertViewControllerIdentifier") as! CustomAlertViewController

        vc.title = title
        vc.message = message
        vc.view = view
        vc.delegate = delegate

        return vc
    }
}

and then use like:

let myCustomAlertViewController = CustomAlertViewController.instantiateFromStoryboard(title: "bla", ...)