程序化NSLayoutConstraint动画问题

时间:2013-05-21 04:24:24

标签: ios animation nslayoutconstraint

所以我试图制作一些布局约束的动画并且运气很糟糕,我只是看不到任何东西然后我得到一条错误消息,说明它不能同时满足所有约束等。

我正在使用一个名为PullableView的类,其动画使用旧样式[UIView commitAnimation],所以我将其子类化并添加到我的代码中,我认为这将是动画约束的动画...没有这样的运气和尝试动画它甚至让它做很多事情证明是困难的我只是得到“无法同时满足约束”。问题是我对这个约束业务相当新,所以我不知道从哪里开始。 / p>

这是错误,另一个是几乎相同但是对于centerY。

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

我在调用此

之前当然会[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];
        }
    }
}

1 个答案:

答案 0 :(得分:11)

有几点想法:

  1. 您在此处创建新约束。通常,您将调整现有约束的constant。或者,如有必要,您将删除旧约束,并添加一个新约束。

  2. 更改现有约束时,有两种方法。一种是迭代视图的约束,找到有问题的约束,然后为此调整constant。另一种方法(当视图是您在Interface Builder中添加的视图时更容易)是在Interface Builder中为约束创建IBOutlet。然后你可以设置动画。

    • This answer,同时关注另一个问题,说明了为约束创建IBOutlet然后动画更改其值的过程。

    • 如果你必须遍历约束来寻找约束(例如,从你可能用可视化格式语言创建的整个集合中挑出一个约束),那么replaceLeadingAndTopWithCenterConstraints就会说明在this answer中可能是一个有用的示例,说明如何在现有视图上找到约束。这个特殊的例子是删除约束并添加一个新约束,但是一旦找到现有约束,就可以轻松地调整其常量。


  3. 我不完全确定你想要的用户体验,但是假设你有一个想要滑到屏幕左侧的面板:

    1. 第一个问题是你定义的约束:在这个例子中,我定义了四个约束,三个超级视图(即顶部,底部和左侧,但不是右)和宽度约束。如果你在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. 您现在可以看到为什么确保没有定义正确的约束很重要。因为如果我在宽度约束定义了右约束时调整左约束,那么它将变得不可满足。通过确保在开始时对约束进行最低限度的定义(虽然明确定义),我可以更改左约束,现在视图就像我想要的那样动画。