2015-12-21 7 views
10

私はconstraintEqualToAnchor()を使って、自動レイアウトの制約を持つビューを設定してみてください:コードの最後の行で自動レイアウト制約は、constraintEqualToAnchor()を使用して設定した後で変更する方法はありますか?

override func viewDidLoad() { 
    super.viewDidLoad() 

    let myView = UIView() 
    myView.backgroundColor = UIColor.orangeColor() 
    myView.translatesAutoresizingMaskIntoConstraints = false 
    view.addSubview(myView) 

    myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor).active = true 
    myView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active = true 
    myView.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true 
    myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor).active = true 

    /******************************************/ 
    /* I try to change one of the constraints */ 
    /******************************************/ 
    myView.leftAnchor.constraintEqualToAnchor(view.rightAnchor, constant: -100).active = true 
} 

、私は、制約の1つを変更してみてください。 constraintEqualToAnchor()?を使用している場合

"<NSLayoutConstraint:0x7fb53a5180d0 H:|-(0)-[UIView:0x7fb53a5190b0](LTR) (Names: '|':UIView:0x7fb53a519240)>", 
"<NSLayoutConstraint:0x7fb53a51f660 H:[UIView:0x7fb53a519240]-(-100)-[UIView:0x7fb53a5190b0](LTR)>", 
"<NSLayoutConstraint:0x7fb53a711ee0 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7fb53a519240(414)]>" 

私はそれが仕事だろうと思ったが、それはコンソールログにいくつかのエラーを与え、私はそれらを設定した後、後に制約を変更する正しい方法は何ですか?

+0

私は偽 'に' myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor).active'を設定すると考えていました'を変更する前に(最後の行)、それでも失敗します。私はここにいくつかの誤解があると思います... –

+0

制約への参照を保持して、定数を直接設定しようとしましたか?ビューに新しい制約を適用し続けることはできません。そうしないと、制約が過度になります。 –

+0

@LucasDerraughレイアウトアンカーでどのように行うのかよくわかりません。答えにコードを表示できますか? –

答えて

21

新しい制約をアクティブにするときは、以前の制約を無効にする必要があります。これにより、ビューが拘束されなくなります。これを行うには、あなたのViewControllerで財産などの制約のそれぞれへの参照を格納し、新しい制約の作成およびアクティブ化する前falseに古い制約のactiveプロパティを設定します。

スウィフト2.xの:

class ViewController: UIViewController { 
    var leftConstraint: NSLayoutConstraint? 
    var trailingConstraint: NSLayoutConstraint? 
    var topConstraint: NSLayoutConstraint? 
    var bottomConstraint: NSLayoutConstraint? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let myView = UIView() 
     myView.backgroundColor = UIColor.orangeColor() 
     myView.translatesAutoresizingMaskIntoConstraints = false 
     view.addSubview(myView) 

     leftConstraint = myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor) 
     leftConstraint?.active = true 

     trailingConstraint = myView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor) 
     trailingConstraint?.active = true 

     topConstraint = myView.topAnchor.constraintEqualToAnchor(view.topAnchor) 
     topConstraint?.active = true 

     bottomConstraint = myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor) 
     bottomConstraint?.active = true 

     /******************************************/ 
     /* I try to change one of the constraints */ 
     /******************************************/ 
     leftConstraint?.active = false 
     leftConstraint = myView.leftAnchor.constraintEqualToAnchor(view.rightAnchor, constant: -100) 
     leftConstraint?.active = true 
    } 
} 

スウィフト3構文の更新:

class ViewController: UIViewController { 
    var leftConstraint: NSLayoutConstraint? 
    var trailingConstraint: NSLayoutConstraint? 
    var topConstraint: NSLayoutConstraint? 
    var bottomConstraint: NSLayoutConstraint? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let myView = UIView() 
     myView.backgroundColor = UIColor.orange 
     myView.translatesAutoresizingMaskIntoConstraints = false 
     view.addSubview(myView) 

     leftConstraint = myView.leftAnchor.constraint(equalTo: view.leftAnchor) 
     leftConstraint?.isActive = true 

     trailingConstraint = myView.trailingAnchor.constraint(equalTo: view.trailingAnchor) 
     trailingConstraint?.isActive = true 

     topConstraint = myView.topAnchor.constraint(equalTo: view.topAnchor) 
     topConstraint?.isActive = true 

     bottomConstraint = myView.bottomAnchor.constraint(equalTo: view.bottomAnchor) 
     bottomConstraint?.isActive = true 

     /******************************************/ 
     /* I try to change one of the constraints */ 
     /******************************************/ 
     leftConstraint?.isActive = false 
     leftConstraint = myView.leftAnchor.constraint(equalTo: view.rightAnchor, constant: -100) 
     leftConstraint?.isActive = true 
    } 
} 
ここで
+0

素晴らしいです、ありがとう!私はなぜ制約を格納するために変数が必要なのだろうと思っています。どうして '.active = false'を直接変更できないのですか?(myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor).active = false)? –

+1

'myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor)'は新しい制約を作成します。それは古いものにアクセスしません。 – vacawama

+0

私は、ありがとう!このような制約の変更をアニメートすることは可能ですか?私は実際に制約を変更することでページスライドイン効果を達成しようとしています。私は 'UIView.animation()'で試したところ、 "constant"を使用しない限りアニメーションはありません(定数を使う必要はないと思います)。 –

2

これは、後で参照される制約cを宣言する例です。新しい一定の値を設定し、スーパービューでlayoutを呼び出します。

myView.translatesAutoresizingMaskIntoConstraints = false 

var constraints: [NSLayoutConstraint] = [ 
    myView.topAnchor.constraintEqualToAnchor(view.topAnchor), 
    myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor), 
    myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor) 
]   
let c = myView.rightAnchor.constraintEqualToAnchor(view.rightAnchor)  
constraints.append(c) 

view.addSubview(myView) 
NSLayoutConstraint.activateConstraints(constraints) 

// Some time later 
c.constant = -100 
view.layout() 
+0

新しい定数を割り当てることは私の問題を解決できません。私は制約を削除し、新しい制約を追加する必要があります。制約を削除/無効にすることは可能ですか? –

+0

私の最後の行は、定数値を変更するだけでなく、新しい制約があることがわかります。左のアンカーは親の左のアンカーと揃えられていて、親の右のアンカーから100を引いたものに合わせて変更したいと思います。これは単なる変更ではありません。 –

+0

私はこの種の定数変更をオンラインで見つけましたが、実行時にプログラマチックに新しい制約を追加できるように、制約を削除/非アクティブ化する方法を見つけることができません。 –

0
// method myView.topAnchor.constraintEqualToAnchor creates new one inactive anchor 
// and not returns exist with equal relationships  

// you can set identifier for any constraint in Interface Builder or code and find & update in code 
for (NSLayoutConstraint *c in [self.view constraintsAffectingLayoutForAxis:UILayoutConstraintAxisHorizontal]) 
{ 
    if (YES == [c.identifier isEqualToString:@"my.layout-constraint.id"]) 
    { 
     // Unlike the other properties, the constant can be modified 
     // after constraint creation. 
     // Setting the constant on an existing constraint performs much better 
     // than removing the constraint and adding a new one that's exactly like 
     // the old except that it has a different constant. 

     c.constant = 123; 

     // if needed 
     // [self.view setNeedsUpdateConstraints]; 

     break; 
    } 
} 
0

StackViewを変更するIF文を使用して、一例であり、セグメント化されたが、クリックしたときに表示します

if (sender as AnyObject).selectedSegmentIndex == 0{ 


     // Shrink the white view and stack view 
     heightConstraintView = containerView.heightAnchor.constraint(equalToConstant: 100) 
     heightConstraintView?.isActive = true 

     heightConstraintStackView = stackView.heightAnchor.constraint(equalToConstant: 100) 
     heightConstraintStackView?.isActive = true 
    } 

    else { 


     // Before returning back the white view and stack view DEACTIVATE teh previous constraints 
     heightConstraintView?.isActive = false 
     heightConstraintStackView?.isActive = false 

     // Returning back the white view and stack view to normal size 
     heightConstraintView = containerView.heightAnchor.constraint(equalToConstant: 200) 
     heightConstraintView?.isActive = true 

     heightConstraintStackView = stackView.heightAnchor.constraint(equalToConstant: 200) 
      heightConstraintStackView?.isActive = true 
    } 
関連する問題