大阪市中央区 システムソフトウェア開発会社

営業時間:平日09:15〜18:15
MENU

swift5 UIAlertController ActionSheetでのconstraint error

株式会社クローバーフィールドの経営理念
著者:津路高広
公開日:2023/12/21
最終更新日:2023/12/21
カテゴリー:技術情報
タグ:

津路です。

当社では、iOSアプリ開発も行っております。
今回は、XCode上で、swiftによる、カメラアプリの試作をしておりまして、シミュレータ上でデバッグしておりました。
Main Storyboard上で、ViewControllerには、View > UIImageViewを配置、下にツールバー > Buttonを配置して、
Buttonをクリックしたときに、UIAlertControllerによるポップアップを表示しようとしました。

        let sheet=UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
        //3 action buttons
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: {(action)->Void in})
        let cameraAction = UIAlertAction(title: "Camera", style: .default, handler: {(action)->Void in pickerController.sourceType = .camera
                                            self.present(pickerController, animated: true, completion: nil)})
        let LibraryAction = UIAlertAction(title: "Library", style: .default, handler: {(action)->Void in pickerController.sourceType = .photoLibrary
                                            self.present(pickerController, animated: true, completion: nil)})
//        sheet.addAction(cancelAction)
//        sheet.addAction(cameraAction)
//        sheet.addAction(LibraryAction)
        self.present(sheet, animated: true, completion: nil)

さて、シミュレータ上で確認しようと、起動したところ、ViewController以下のViewは、正常に表示されたものの、Buttonをクリックすると、

<[LayoutConstraints] 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. ( "
)

Will attempt to recover by breaking constraint

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in may also be helpful.

この類のエラーは、有名で、AutoLayoutを設定しているものの、課されたサイズと位置に対する制約がうまくいかないというエラーです。
しかし、-16という値をwidthに設定した覚えがないので、曖昧なので、自動的に設定されたのかと考えました。

そこで、preferredStyle: .alert に変更したところ、”UIAlertController must have a title, a message or an action to display”が出ました。
それは簡単なのですが、やはり下からポップアップして欲しいので、actionSheetに戻し、実行した状態で、各ビューのサイズを確認することにしました。
Debug > View Debugging > Capture View Hierarchy を選んだところ、

Googleで調べましたら、http://openradar.appspot.com/49289931 に書かれている通り、2019年から存在するバグだそうです。
Qiitaに記事が見つかりました。
https://qiita.com/akatsuki174/items/b6a0390a1b80cc195d10
この記事によると、解決策は、UIAlertControllerをextendsして、constraintをなくしてしまうことです。
が、私は、stackoverflowの関連スレッドを見て、自動的につけられてしまう-16を正の値に書き換える方法を採用させていただきました。

        for subview in self.view.subviews {
            for constraint in subview.constraints {
                if constraint.firstAttribute == .width && constraint.constant == -16 {
                    constraint.constant = 10 // Any positive value
                }
            }
        }
    上に戻る