'UIAlertController Unable to satisfy constraints

I am converting all my UIActionSheet and UIAlertView with UIAlertController.

My problem is when I try to present a UIAlertController of style ActionSheet. Here is my code :

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Title"
                                                               message:@"My message"
                                                        preferredStyle:UIAlertControllerStyleActionSheet];

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:cancelAction];

UIAlertAction *OKAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:OKAction];

UIAlertAction *destroyAction = [UIAlertAction actionWithTitle:@"Destroy" style:UIAlertActionStyleDestructive handler:nil];
[alert addAction:destroyAction];

UIPopoverPresentationController *popPresenter = [alert popoverPresentationController];
popPresenter.sourceView = self.view;
popPresenter.sourceRect = self.view.bounds;

[self presentViewController:alert animated:YES completion:nil];

Here is the error :

Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you 
don't want. Try this: 
(1) look at each constraint and try to figure out which you don't expect; 
(2) find the code that added the unwanted constraint or constraints and fix it. 
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property 
translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7c00ab40 H:[UIView:0x7c0764c0(304)]>",
    "<NSLayoutConstraint:0x7b6c7f80 _UIAlertControllerView:0x7b6c2e50'title'.width >= UIView:0x7b6c3230.width>",
    "<NSLayoutConstraint:0x7ccdfe40 _UIAlertControllerView:0x7b6c2e50'title'.width == UIView:0x7b6efbe0.width>",
    "<NSAutoresizingMaskLayoutConstraint:0x7c33b9d0 h=--& v=--& H:[UIView:0x7c1094e0(0)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7c00ab40 H:[UIView:0x7c0764c0(304)]>

Thank you all.



Solution 1:[1]

I also encounter a similar problem in present a UIAlertController of style ActionSheet.

One more possible reason of this is setting the permittedArrowDirections of UIPopoverPresentationController wrongly. In my case, the sourceView of the popover is located at the top, but I have set the permittedArrowDirections to UIPopoverArrowDirectionDown which causes "Unable to simultaneously satisfy constraints" error. The error is gone after I set it to UIPopoverArrowDirectionUp.

Solution 2:[2]

I was having the same problem because I did not initially understand that the sourceView and sourceRect have to refer to the button/view that is pressed in connection with the action sheet. This way the popover appears next to it. If instead one uses the entire view, then the popover would appear outside the screen, which creates the constraints errors.

Solution 3:[3]

I was getting this error because I was focused on a UITextField. First of all UITextField seems a little problematic, so the code below from this SO post enabled me to solve that,

extension UIView
{
    func fixInputAssistant()
    {
        for subview in self.subviews
        {
            if type(of: subview) is UITextField.Type
            {
                let item = (subview as! UITextField).inputAssistantItem
                item.leadingBarButtonGroups = []
                item.trailingBarButtonGroups = []
            }
            else if subview.subviews.count > 0
            {
                subview.fixInputAssistant()
            }
        }
    }
}

But then on validating my UITextField's my UIAlertController would kick up the constraint conflict you mention. To resolve this I needed to lose focus before showing my UIAlertController, thus

firstName.resignFirstResponder()
surname.resignFirstResponder()
emailAddress.resignFirstResponder()
... etc...

Note sure if this is relevant to your particular scenario, but be aware it could be to do with UITextField focus.

Solution 4:[4]

I recently faced this issue myself, and while the existing answers on this question did help, there's some extra information I found useful:

  • This error appears to happen when the given parameters would cause the alert to draw offscreen
  • You must provide either barButtonItem or both sourceView and sourceRect. If you only provide sourceView or sourceRect (not both), your app will crash (at least it did for me).
  • When providing sourceView and sourceRect, sourceRect is relative to sourceView, not the origin of the view controller presenting the alert
  • sourceView and sourceRect can be anything and don't have to be related to the button pressed as Fil's answer indicates

Chubao's answer saying to set the permitted arrow direction to Any does help fix the issue since as long as the given sourceRect is onscreen, the UIKit will pick the best arrow direction that allows the alert to be onscreen as well. However, if you are providing what you think is a valid arrow direction and run into this error, it seems more likely that you may have goofed and provided a sourceView and/or sourceRect that you didn't intend to, leading to an unexpected position of the alert, and it might be worth making sure you're passing the correct sourceView and sourceRect.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 chubao
Solution 2 Fil
Solution 3
Solution 4 Adam Evans