The sourceViewController
is likely to be exiting the view hierarchy after a segue, so if a controller is presented there, it will be dismissed immediately.
The destinationViewController
may not be present in the view hierarchy by prepareForSegue there, so if you present it there, you may get
2016-08-23 10:22:22.354 Foo[589:137407] Warning: Attempt to present <UIAlertController: 0x17eb0e00> on <Foo.DestinationViewController: 0x177e7b60> whose view is not in the window hierarchy!
2016-08-23 10:22:22.904 Foo[589:137407] Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (<UIAlertController: 0x17eb0e00>)
One possibility is to add an ivar onto your destinationViewController like so.
class DestinationViewController: UIViewController {
var presentWhenAppearing: UIViewController? = nil
override func viewWillAppear(animated: Bool) {
if let p = presentWhenAppearing {
self.presentViewController(p, animated: true, completion: nil)
presentWhenAppearing = nil
}
}
}
which can then be used inside prepareForSegue
as follows
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "myIdentifier" {
guard let destinationVC = segue.destinationViewController as? DestinationViewController else {
fatalError("Unexpected VC")
}
let alert = UIAlertController(title: "You are currently offline", message: "but your download willl be begin and continue when you have an internet connection.", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
destinationVC.presentWhenAppearing = alert
}
}
See also How to present UIAlertController when not in a view controller? for other answers that might work here.