LoginSignup
9
9

More than 3 years have passed since last update.

ActionSheet で width == - 16 の Auto Layout 警告が出た時の対処法

Posted at

単純なレイアウトで UIAlertControlleractionSheet を使ったときになぜか Auto Layout がうまく言ってないようだったのでメモ。

現象

ここでは例としてボタンをタップしたらアクションシートを表示するだけのコードを用意しました。

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func showActionSheet(_ sender: Any) {
        let alert = UIAlertController(title: "title", message: "message", preferredStyle: .actionSheet)
        let defaultAction = UIAlertAction(title: "item", style: .default, handler: nil)
        alert.addAction(defaultAction)
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
        alert.addAction(cancelAction)
        present(alert, animated: true, completion: nil)
    }
}

IMG_2B79FE610AF4-1.jpeg

これを Xcode 11.4, iOS 13.3 の端末で実行すると、こんなログがだらだらと流れてきました。

2020-05-10 22:14:35.759481+0900 UIKitCustomCollection[53013:10180992] [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. 
(
    "<NSLayoutConstraint:0x2806e9720 UIView:0x103e0d040.width == - 16   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x2806e9720 UIView:0x103e0d040.width == - 16   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
(lldb) 

幅が16のコンテンツに覚えはないし <NSLayoutConstraint:0x2806e9720 UIView:0x103e0d040.width == - 16 (active)> と言われているので、ViewHierarchyで 0x103e0d040 を絞り込んでみたところ、UIAlertController の中の要素っぽいです。

スクリーンショット 2020-05-10 22.16.09.png

原因

いろいろググってみたところ、iOS 12.2 から(少なくとも iOS 13.4 まで)存在している、OS 側のバグのようです。
Radarはこちら。
Action sheet causes LayoutConstraints warning

対処法

うまくいった対処法は以下の Stack Overflow の方法です。
https://stackoverflow.com/questions/55653187/swift-default-alertviewcontroller-breaking-constraints

extension UIAlertController {
    override open func viewDidLoad() {
        super.viewDidLoad()
        pruneNegativeWidthConstraints()
    }

    private func pruneNegativeWidthConstraints() {
        for subView in self.view.subviews {
            for constraint in subView.constraints where constraint.debugDescription.contains("width == - 16") {
                subView.removeConstraint(constraint)
            }
        }
    }
}

本当に今回のバグで発生した width == - 16 だけを remove してるのか少し不安なところですが、おそらくこれ以外の原因では width == - 16 警告は発生しないのでは…。

おまけ

animetedfalse にすると解決するという情報もありましたが、私には効果がありませんでした。

9
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9