0
votes

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!

Screenshot

1
I don't quite understand your issue; Are you trying to present the 'block' view while the alert view is already on screen?Paulw11
@Paulw11 no I am trying to do both separately. I'll add a screenshotJames M

1 Answers

0
votes

I've figured out the issue. As you can see in the picture below, there is an action for the declineUser button that somehow got inside the action for the back button:

Bad IBAction

Once I delete that so there is only one IBAction for the declineUser button, it works. The app was getting confused to which view the button was on and which was triggering the action, thus throwing a view hierarchy error. Lesson learned: always check how your IBOutlets and IBActions are set up!