2013-05-21 10 views
5

ので、私はいくつかのレイアウト上の制約をアニメーション化しようとしていると悲惨な運を持っています、私はちょうど何も見えいけないし、私はそれは同時になど、すべての制約を満たすことができないかというエラーメッセージが表示されますプログラムによるNSLayoutConstraintアニメーションの問題

私はPullableViewと呼ばれるクラスを使用しています。そのアニメーションは古いスタイル[UIView commitAnimation]を使用していますので、サブクラス化して、制約をアニメーション化するためのコードを追加しました...そのような運とそれをアニメーション化するか、何かの難しさを証明している私はちょうど "同時に制約を満たすことができません" ..問題は、私はかなりこの制約のビジネスに新しいので、私はどこから始めるべきか分からないだろう。

ここにエラーがあります。もう1つはほぼ同じですがcenterYです。当然の

"<NSLayoutConstraint:0x7c8a3a0 StyledPullableView:0x905a9b0.centerX == UIView:0x9054680.centerX>", "<NSLayoutConstraint:0x7c6b480 StyledPullableView:0x905a9b0.centerX == UIView:0x9054680.centerX + 128>"

I任意のヘルプ感謝この

を呼び出す前に[pullRightView setTranslatesAutoresizingMaskIntoConstraints:NO];を行います。

- (void)setOpenedForConstraints:(BOOL)op animated:(BOOL)anim 
{ 
    opened = op; 

    if (anim) 
    {   
     NSLayoutConstraint *constraintX = [NSLayoutConstraint constraintWithItem:self 
                       attribute:NSLayoutAttributeCenterX 
                       relatedBy:NSLayoutRelationEqual 
                        toItem:_parentView 
                       attribute:NSLayoutAttributeCenterX 
                       multiplier:1 
                       constant:0]; 

     NSLayoutConstraint *constraintY = [NSLayoutConstraint constraintWithItem:self 
                       attribute:NSLayoutAttributeCenterY 
                       relatedBy:NSLayoutRelationEqual 
                        toItem:_parentView 
                       attribute:NSLayoutAttributeCenterY 
                       multiplier:1 
                       constant:0]; 

     [_parentView addConstraint:constraintX]; 
     [_parentView addConstraint:constraintY]; 

     constraintX.constant = opened ? self.openedCenter.x : self.closedCenter.x; 
     constraintY.constant = opened ? self.openedCenter.y : self.closedCenter.y; 
    } 

    if (anim) 
    { 

     // For the duration of the animation, no further interaction with the view is permitted 
     dragRecognizer.enabled = NO; 
     tapRecognizer.enabled = NO; 

     //[UIView commitAnimations]; 

     [UIView animateWithDuration:animationDuration 
         animations:^ 
     { 
      [self layoutIfNeeded]; 
     }]; 

    } 
    else 
    { 

     if ([delegate respondsToSelector:@selector(pullableView:didChangeState:)]) 
     { 
      [delegate pullableView:self didChangeState:opened]; 
     } 
    } 
} 

答えて

11

思考のカップル:

  1. あなたはここに新しい制約を作成しています。通常は、既存の制約のconstantを調整します。または、必要に応じて古い制約を削除し、新しい制約を追加します。

  2. 既存の制約を変更する場合、2つのアプローチがあります。 1つは、ビューの制約を繰り返し、問題のものを見つけてから、constantを調整することです。もう1つのアプローチ(そして、ビューがInterface Builderで追加したビューの方がはるかに簡単です)は、Interface Builderで制約のためにIBOutletを作成することです。その後、それをアニメ化することができます。

    • This answer、別の問題に着目して、制約のIBOutletを作成し、その値の変化をアニメーション化するプロセスを示します。

    • あなたが(例えば、例えばあなたが視覚的形式の言語で作成された可能性があり、コレクション全体のうちの1つの制約を選び出す)制約を探して制約を反復処理する必要がある場合は、this answerに示すreplaceLeadingAndTopWithCenterConstraintsがあるかもしれません既存のビューに対する制約の検索方法の参考例です。この特定の例では、制約を削除して新しい制約を追加していますが、既存の制約を見つけたら、定数を調整することもできます。


私はあなたのために行っているUXの完全わからないんだけど、あなたはあなたが画面の左にオフにスライドしたいパネルを持っているとしましょう:

  1. 最初の問題は、あなたが定義した制約です。この例では、4つの制約が定義されています.3つはスーパービュー(つまり、上、下、左ですが、ではなく、です) 。また、IBでこれを行っている場合は、細かいことがあります(たとえば、幅制約を追加するまでは右の制約を削除できません)。制約が完全に定義されていることを確認してください。

  2. その後、私はちょうど左制約のconstantを変更することにより、画面の外パネルのスライドをアニメーション化することができます:何の権利がなかったことを確認することが重要だった理由

    - (IBAction)touchUpInsideButton:(id)sender 
    { 
        self.offscreen = !self.offscreen; 
    
        [UIView animateWithDuration:0.5 
            animations:^{ 
             self.panelLeftConstraint.constant = ([self isOffscreen] ? -kHowMuchToSlideOffToLeft : 0.0); 
             [self.view layoutIfNeeded]; 
            }]; 
    } 
    
  3. あなたは今見ることができます定義された制約。私が幅制約の右の制約を定義しているときに左の制約を調整した場合、それは満足できなくなります。最初に制約が最小限に定義されている(確実に定義されていますが)ことを確認することで、左の制約を変更することができ、ビューをアニメーション化することができます。答えを

+0

おかげで、私はこれらを通じて探求します私はinit関数でそれを行うが...私も...新しいものを追加する前に、すべての制約を削除... – Genhain

+1

私はそれがだと思う@Genhain追加や削除よりも制約を変更する方がはるかに簡単です。最初にビューに対して定義した制約は非常に注意してください。たとえば、私はそれを左にスライドさせようとしていた場合、上、下、左、および幅で定義されていましたが(しかし右ではありません)、左の制約の定数を変更することでアニメーション化できます。改訂版の回答を参照してください。私はあなたが望んでいるUXがあなたのコードサンプルであったものを解読することができなかったと告白しなければならないので、何を達成しようとしているのかを明確にすればもっと役に立ちます。 – Rob

+0

偉大な答えですが、最初のリストの第2ポイントが間違っています。 layoutIfNeededのみがアニメーションブロック内になければなりません。 – jrturton

関連する問題