web-dev-qa-db-ja.com

ビューコントローラーマージンにバインドされた制約をプログラムで作成する

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])
13
prawn

実際、コードの問題は、translatesAutoresizingMaskIntoConstraintsmyviewfalseに設定しなかったことです。自動レイアウト制約を使用する場合は、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))
49

上記のコード例では、いくつかの場所でviewmyViewを混ぜているようです。いずれにしても、widthConstraintmyViewに追加し、topConstrainttrailingConstraint、およびbottomConstraintself.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

右側のビューなどに制約を明示的に追加する必要はありません。この方法で制約を作成する方法の詳細については、こちらをご覧ください。

https://developer.Apple.com/library/ios/documentation/AppKit/Reference/NSLayoutAnchor_ClassReference/

そしてここ:

https://developer.Apple.com/library/ios/documentation/AppKit/Reference/NSLayoutDimension_ClassReference/

9
Daniel Hall

あなたのコードにはいくつかの曖昧さがあります。myViewとしてUIViewを作成していますが、self.viewにビューを追加し、ビュー自体にも制約を追加しています。コードを修正し、ビューをmyViewに置き換えます。次に、TranslayesAutoresizingMaskIntoConstraintsをfalseに設定します。次に、すべての制約をself.viewに追加します。これで問題が解決するはずです。

 myView.setTranslatesAutoresizingMaskIntoConstraints(false)
 self.view.addConstraints([trailingConstraint, bottomConstraint, widthConstraint])

VFLは、より優れたクリーンなアプローチでもあります。実際には、制約の設定方法を視覚化できます。

0
Arun Gupta