ios - 程序化 NSLayoutConstraint 动画问题

标签 ios animation nslayoutconstraint

所以我试图为一些布局约束设置动画,但运气很差,我什么也没看到,然后我收到一条错误消息,说明它如何不能同时满足所有约束等。

我正在使用一个名为 PullableView 的类谁的动画用的是旧风格[UIView commitAnimation]所以我对它进行了子类化并在我的代码中添加了我认为用于动画约束的东西......没有这样的运气并且试图为其制作动画甚至让它做很多事情被证明是困难的我只是得到“无法同时满足约束”。问题是我对这个约束业务还很陌生,所以我不知道从哪里开始。

这是错误,另一个几乎相同,但针对 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. 您正在此处创建新的约束。通常,您将调整现有约束的 constant。或者,如有必要,您将删除旧约束并添加新约束。

  2. 更改现有约束时,有两种方法。一种是遍历 View 的约束,找到有问题的约束,然后为此调整 constant。另一种方法(当 View 是您在 Interface Builder 中添加的 View 时要容易得多)是在 Interface Builder 中为约束创建一个 IBOutlet。然后你可以为它制作动画。

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

    • 如果您必须遍历约束来寻找约束(例如,从您可能使用视觉格式语言创建的整个集合中挑选出一个约束),那么 replaceLeadingAndTopWithCenterConstraintsthis answer中说明可能是一个有用的示例,说明您如何在现有 View 上找到约束。这个特定示例是删除一个约束并添加一个新约束,但是您可以同样轻松地在找到现有约束后调整其常量。


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

  1. 第一个问题是您定义了哪些约束:在这个示例中,我定义了四个约束,其中三个到父 View (即顶部、底部和左侧,但不是右)和宽度约束。如果你在 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. 您现在可以明白为什么确保没有定义正确的约束很重要了。因为如果我在定义了宽度约束 右约束的同时调整了左约束,那么它将变得无法满足。通过确保在开始时对约束进行最低限度的定义(尽管定义明确),我可以更改左侧约束,并且 View 现在可以按照我想要的方式进行动画处理。

关于ios - 程序化 NSLayoutConstraint 动画问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16662132/

相关文章:

iphone - TabBarImage大小不正确

iphone - CGAfflineTransform UIView 和 CoreGraphics 冲突

ios - 无法以编程方式重置 UINavigationController.presentedViewController

Swift3 迁移问题

ios - UIToolbar 与 UIBarButtonItem LayoutConstraint 问题

ios - 如何解决我的 UICollectionView 的 "removeConstraint() not working"问题?

ios - RLM 异常 : 'Primary key property ' serial' does not exist on object 'Book' Migrating to Swift 4

android - 单击按钮时动画不会第二次应用

javascript - 动画网站缩放/缩放

iphone - 如何使 View 像揉皱的纸一样动画