OGeek|极客世界-中国程序员成长平台

标题: ios - 使用 AutoLayout 将 UIImageView 从中心动画到父 UIView 顶部的 20 点 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-12 13:23
标题: ios - 使用 AutoLayout 将 UIImageView 从中心动画到父 UIView 顶部的 20 点

当我对 UIImageView 和父 UIView 顶部之间的距离使用约束时,动画本身可以工作,而无需垂直和水平居中。

UIImageView 的约束:

当我使用这个动画时效果很好:

self.logoImageViewVerticalSpaceConstraint.constant = 20;

[UIView animateWithDuration: 1.0
                      delay: 0
                    optionsUIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionAllowUserInteraction)                     
                 animations:^{[self.logoImageView layoutIfNeeded];}
                 completion:^(BOOL finished) {NSLog(@"Finished animation"); }];

当我不想使用静态空间来顶部布局约束时,问题就出现了,因为 ImageView 需要居中以用于 3.5 和 4 英寸设备。为了解决这个问题,我想从垂直和水平中心约束开始。

现在我想我可以简单地删除 y 中心约束并自己将空间添加到 20pt 的顶部布局约束:

[self.logoImageView removeConstraint:self.logoImageViewYCenterConstraint];

NSLayoutConstraint *topSpaceConstraint = [NSLayoutConstraint  
constraintWithItem:self.view                                                                         attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual                                                                                    toItem:self.logoImageView
attribute:NSLayoutAttributeTop                                                                                multiplier:1
constant:20];
    [self.view addConstraint:topSpaceConstraint];

    [UIView animateWithDuration: 1.0
                          delay: 0
                        optionsUIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionAllowUserInteraction)                     
                        animations:^{
                           [self.logoImageView layoutIfNeeded];
                        }
                        completion:^(BOOL finished) { 
                           NSLog(@"Finished animate"); 
                        }];

结果是 UIImageView 保持居中并且有点爆炸。 这与我期望发生的完全相反,因为我删除了 x 中心约束。将距离为 20pt 的顶部约束添加到父 UIView 的顶部,我没有触及任何其他约束(如宽度和高度)。



Best Answer-推荐答案


一个 NSLayoutConstraint 有一个或两个被它约束的 View 。在您的情况下, View 是 self.logoImageViewself.view

要产生任何效果,约束必须安装在 View 上,而不仅仅是任何 View 。约束必须安装在两个受约束 View 的共同祖先上。 (请注意, View 被认为是其自身的祖先。)当您移除约束时,您必须将其从安装它的 View 中移除

您正试图从 self.logoImageView 中移除居中约束,但该约束无法安装在该 View 上。

从 iOS 8.0 开始,卸载约束的首选(也是最简单)方法是将其 active 属性设置为 NO:

self.logoImageViewYCenterConstraint.active = NO;

在 iOS 8.0 之前,您必须从安装它的 View 中删除它。约束可能安装在 self.view 上。所以试试这个:

[self.view removeConstraint:self.logoImageViewYCenterConstraint];

另请注意,如果您想将 ImageView 动画化回中心,则需要卸载 topSpaceConstraint 并重新安装 self.logoImageViewYCenterConstraint

解决此问题的另一种方法是同时安装两个约束,但给其中一个较低的优先级。当你需要改变 ImageView 的位置时,改变约束的优先级。因此:

- (void)viewDidLoad {
    [super viewDidLoad];
    if (self.topSpaceConstraint == nil) {
        self.topSpaceConstraint = [NSLayoutConstraint constraintWithItem:...];
        self.topSpaceConstraint.priority = 1;
        [self.view addConstraint:self.topSpaceConstraint];
    }
}

- (void)setImageViewCenteredVerticallyBOOL)isCentered animatedBOOL)animated {
    if (isCentered) {
        self.topSpaceConstraint.priority = 1;
        self.logoImageViewYCenterConstraint.priority = UILayoutPriorityRequired;
    } else {
        self.topSpaceConstraint.priority = UILayoutPriorityRequired;
        self.logoImageViewYCenterConstraint.priority = 1;
    }

    if (animated) {
        [UIView animateWithDuration:1 delay:0
            options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
            animations:^{
                [self.view layoutIfNeeded];
            }
            completion:nil];
    }
}

关于ios - 使用 AutoLayout 将 UIImageView 从中心动画到父 UIView 顶部的 20 点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18112769/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://ogeek.cn/) Powered by Discuz! X3.4