View Controllerの右側に取り付けられた一種の「パネル」として機能するビューを作成しようとしています。
つまり、静的な幅は300で、親View Controllerの末尾、上部、および下部の余白にバインドされます
しかし、私はちょうどそれを正しくすることができないようです、私は制約を破るか、xcodeが私に違法であると言う何かをしているのです。
私は何を間違えていますか?
これがコントローラーのコードです
let myView = UIView()
view.backgroundColor = UIColor.redColor()
self.view.addSubview(view)
let topConstraint = NSLayoutConstraint(item: myView,
attribute: .Top,
relatedBy: .Equal,
toItem: self.topLayoutGuide,
attribute: .Bottom,
multiplier: 1,
constant: 0)
let trailingConstraint = NSLayoutConstraint(item: self.view,
attribute: .TrailingMargin,
relatedBy: .Equal,
toItem: myView,
attribute: .Trailing,
multiplier: 1,
constant: 0)
let bottomConstraint = NSLayoutConstraint(item: self.bottomLayoutGuide,
attribute: .Top,
relatedBy: .Equal,
toItem: myView,
attribute: .Bottom,
multiplier: 1,
constant: 0)
let widthConstraint = NSLayoutConstraint(item: myView,
attribute: .Width,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1,
constant: 300)
self.view.addConstraints([trailingConstraint])
view.addConstraints([topConstraint, bottomConstraint, widthConstraint])
実際、コードの問題は、translatesAutoresizingMaskIntoConstraints
のmyview
をfalse
に設定しなかったことです。自動レイアウト制約を使用する場合は、translatesAutoresizingMaskIntoConstraints
を設定する必要があります。 falseのビュー。別の問題は、self.viewにmyview
を追加しないことです。コードを更新しましたが、制約に従って正常に動作します。
以下のコードをViewControllerに入れます。
let myView = UIView()
myView.backgroundColor = UIColor.redColor()
self.view.addSubview(myView)
myView.translatesAutoresizingMaskIntoConstraints = false
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .Top, relatedBy: .Equal, toItem: self.topLayoutGuide, attribute: .Bottom, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .Bottom, relatedBy: .Equal, toItem: self.bottomLayoutGuide, attribute:.Top, multiplier: 1, constant: 20))
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute,multiplier: 1, constant: 300))
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .TrailingMargin, relatedBy: .Equal, toItem: view, attribute: .TrailingMargin, multiplier: 1, constant: 0))
上記のコード例では、いくつかの場所でview
とmyView
を混ぜているようです。いずれにしても、widthConstraint
をmyView
に追加し、topConstraint
、trailingConstraint
、およびbottomConstraint
をself.view
に追加する必要があります。この理由は、制約に関係する両方のビューをレイアウトする最も近いスーパービューの祖先に制約を追加する必要があるためです。子ビューの属性をその親ビューの属性に制約する場合、制約はそれ自体と子ビューの両方をレイアウトするため、親ビューに追加する必要があります。 2つの兄弟ビューの間に制約がある場合、制約は親ビューに追加されます。これは、関係する両方のビューをレイアウトする最も近い祖先であるためです。
IOS 9.0以降をターゲットにできる場合、これらの種類の制約を作成するために新しいNSLayoutAnchorおよびNSLayoutDimension APIを使用する方がはるかにクリーンで簡単です。また、厳密な型チェックを提供し、コンパイラーが正しいことを検証できます。これらの新しいAPIを使用すると、サンプルコードは次のようになります。
let myView = UIView()
myView.backgroundColor = UIColor.redColor()
self.view.addSubview(myView)
let margins = self.view.layoutMarginsGuide
myView.trailingAnchor.constraintEqualToAnchor(margins.trailingAnchor).active = true
myView.topAnchor.constraintEqualToAnchor(margins.topAnchor).active = true
myView.bottomAnchor.constraintEqualToAnchor(margins.bottomAnchor).active = true
myView.widthAnchor.constraintEqualToConstant(300.0).active = true
右側のビューなどに制約を明示的に追加する必要はありません。この方法で制約を作成する方法の詳細については、こちらをご覧ください。
そしてここ:
あなたのコードにはいくつかの曖昧さがあります。myViewとしてUIViewを作成していますが、self.viewにビューを追加し、ビュー自体にも制約を追加しています。コードを修正し、ビューをmyViewに置き換えます。次に、TranslayesAutoresizingMaskIntoConstraintsをfalseに設定します。次に、すべての制約をself.viewに追加します。これで問題が解決するはずです。
myView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addConstraints([trailingConstraint, bottomConstraint, widthConstraint])
VFLは、より優れたクリーンなアプローチでもあります。実際には、制約の設定方法を視覚化できます。