I'm building a chat app where there are two types of views to be modally presented over the chat screen: a UIAlertController for users to select media to send, and a popover if the current user wants to block/remove the user that they're messaging. The UIAlertController comes up fine, but the blocking popover fails with this warning:
"Warning: Attempt to present on whose view is not in the window hierarchy!"
Here is the presentation flow: an "inbox" view controller presents a "chat" view controller. This "chat" view controller is the one that presents the modal UIAlertController and the "block" view controller (also modal, over current context). Here is my code where I deal with both of these modal views:
UIAlertController:
@IBAction func mediaBtnWasPressed(_ sender: Any) {
let alert = UIAlertController(title: "Glymps", message: "Please select a source:", preferredStyle: UIAlertController.Style.actionSheet)
let camera = UIAlertAction(title: "Take a picture", style: UIAlertAction.Style.default) { (_) in
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera) {
self.picker.sourceType = .camera
self.present(self.picker, animated: true, completion: nil)
} else {
print("Option unavailable.")
}
}
let video = UIAlertAction(title: "Take a video", style: UIAlertAction.Style.default) { (_) in
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera) {
self.picker.sourceType = .camera
self.picker.mediaTypes = [String(kUTTypeMovie)]
self.picker.videoExportPreset = AVAssetExportPresetPassthrough
self.picker.videoMaximumDuration = 30
self.present(self.picker, animated: true, completion: nil)
} else {
print("Option unavailable.")
}
}
let library = UIAlertAction(title: "Choose an image or video", style: UIAlertAction.Style.default) { (_) in
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary) {
self.picker.sourceType = .photoLibrary
self.picker.mediaTypes = [String(kUTTypeImage), String(kUTTypeMovie)]
self.present(self.picker, animated: true, completion: nil)
} else {
print("Option unavailable.")
}
}
let cancel = UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: nil)
alert.addAction(camera)
alert.addAction(video)
alert.addAction(library)
alert.addAction(cancel)
self.present(alert, animated: true, completion: nil)
}
Block View Controller:
@IBAction func declineBtnWasPressed(_ sender: Any) {
// remove user from current user message requests and matches
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let declineUserVC = storyboard.instantiateViewController(withIdentifier: "DeclineUserVC") as! DeclineUserVC
declineUserVC.userId = self.userId
self.present(declineUserVC, animated: true, completion: nil)
}
I understand similar questions have been asked before for this issue on iOS (Swift), but they explain solutions relative to using a root view controller. I am not trying to use a root view controller. This problem is occurring since the UIAlertViewController is on this screen and supposedly taking priority in the view hierarchy. How do I add the declineUserVC to the hierarchy or have it take higher priority? Thank you in advance!