AutoLayoutをコードで記述するときの注意点

問題

AutoLayoutの制約を記述していたら、ビルドは通るが、実行時にエラーが出て落ちた。

*** Terminating app due to uncaught exception ‘NSGenericException’, reason: ‘Unable to activate constraint with anchors and because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That’s illegal.’

// イメージピッカーボタン
let button = UIButton(type: .contactAdd)
button.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
    button.widthAnchor.constraint(equalToConstant: 50),
    button.heightAnchor.constraint(equalToConstant: 50),
    button.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
    button.topAnchor.constraint(equalTo: self.view.topAnchor)
    ])

self.view.addSubview(button)

widthとheightのconstaintは問題ないが、
trailingとtopの方で、落ちる。

原因

constraint(equalTo: NSLayoutAnchor)は、制約をかけたいviewを追加した後に行う必要があった

修正

addSubViewしたあとに
constaintの設定をする

// イメージピッカーボタン
let button = UIButton(type: .contactAdd)
button.translatesAutoresizingMaskIntoConstraints = false

self.view.addSubview(button)

NSLayoutConstraint.activate([
    button.widthAnchor.constraint(equalToConstant: 50),
    button.heightAnchor.constraint(equalToConstant: 50),
    button.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
    button.topAnchor.constraint(equalTo: self.view.topAnchor)
    ])