设备旋转时是不是有动画自动布局(约束)?

Posted

技术标签:

【中文标题】设备旋转时是不是有动画自动布局(约束)?【英文标题】:Is there something to animate autolayout (constraints) when device rotates?设备旋转时是否有动画自动布局(约束)? 【发布时间】:2014-11-22 22:05:27 【问题描述】:

如我所见,AutoLayouts 旋转动画之前立即设置。对于过渡动画(例如缩放),我必须从-(void)willRotateToInterfaceOrientation 调用我的自定义方法。 那么,当设备旋转时,是否有一些动画自动布局(约束)?

UPD:我检查了一下,它确实有效,但仅限于视图。有什么可以使用标签的吗?

// UIView
UIView *yellowView = [[UIView alloc] init];
yellowView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:yellowView];
yellowView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:yellowView
                                                      attribute:NSLayoutAttributeLeading
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self.view
                                                      attribute:NSLayoutAttributeLeading
                                                     multiplier:1
                                                       constant:40]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:yellowView
                                                      attribute:NSLayoutAttributeTrailing
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self.view
                                                      attribute:NSLayoutAttributeTrailing
                                                     multiplier:1
                                                       constant:-40]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:yellowView
                                                      attribute:NSLayoutAttributeTop
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self.view
                                                      attribute:NSLayoutAttributeTop
                                                     multiplier:1
                                                       constant:40]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:yellowView
                                                      attribute:NSLayoutAttributeBottom
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self.view
                                                      attribute:NSLayoutAttributeBottom
                                                     multiplier:1
                                                       constant:-40]];
[yellowView layoutIfNeeded];

// UILabel
UILabel *greenLabel = [[UILabel alloc] initWithFrame:self.view.frame];
greenLabel.backgroundColor = [UIColor greenColor];
[self.view addSubview:greenLabel];
greenLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:greenLabel
                                                      attribute:NSLayoutAttributeLeading
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self.view
                                                      attribute:NSLayoutAttributeLeading
                                                     multiplier:1
                                                       constant:40]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:greenLabel
                                                      attribute:NSLayoutAttributeTrailing
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self.view
                                                      attribute:NSLayoutAttributeTrailing
                                                     multiplier:1
                                                       constant:-40]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:greenLabel
                                                      attribute:NSLayoutAttributeTop
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self.view
                                                      attribute:NSLayoutAttributeTop
                                                     multiplier:1
                                                       constant:40]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:greenLabel
                                                      attribute:NSLayoutAttributeBottom
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self.view
                                                      attribute:NSLayoutAttributeBottom
                                                     multiplier:1
                                                       constant:-40]];
[greenLabel layoutIfNeeded];

UPD2:我测试动画,它看起来像 UILabels 问题。标签缩小而不是动画。

UILabel *pupureLabel = [[UILabel alloc] init];
pupureLabel.backgroundColor = [UIColor pupureColor];
[self.view addSubview:pupureLabel];
pupureLabel.frame = CGRectMake(0, 0, 320, 568);
[UIView animateWithDuration:1
    animations:^
        pupureLabel.frame = CGRectMake(0, 0, 100, 60);
    ];

【问题讨论】:

你的问题很模糊。你的意思是动画现在不流畅?然后你最好给出一些关于如何设置的代码。你的意思是你在旋转之前改变了约束?或者您的意思是,您出于调试原因想查看它们? 你不明白 - 现在有没有动画。约束立即生效! 在模拟器中打开“慢动作动画”并开始旋转设备,这样您就会看到。当设备开始旋转时,约束立即改变 - 没有动画。您可能会看到旋转动画,但没有自动布局动画。 约束动画对我来说很好。这就是为什么我问你在做什么。您是在 Interface Builder 中还是在源代码中设置约束?你在轮换之前改变它们吗?你和他们做其他事情吗?显示一些代码。例如,您的自定义方法有什么作用? 嗯...我检查了一下,它确实有效,但仅限于视图。有什么可以使用标签的吗? 哇。你说的对。我只是自己尝试了一下,它也对我不起作用。对我来说,这似乎是一个明确的错误;向苹果报告。这似乎也是一个较老的问题,请参见例如this other question 【参考方案1】:

UILabel 在 AutoLayout 约束方面有点奇怪。它定义了一个intrinsicContentSize,它是从它包含的文本中计算出来的。 intrinsicContentSize 充当隐式约束:它固定标签的宽度和高度。因此,如果您还向标签添加了前导和尾随约束,那么您就会有冲突的约束,从而导致您看到的行为。

这种行为对于多行标签来说很复杂,由preferredMaxLayoutWidth 决定它的首选宽度是多少。

话虽如此,我仍然认为它仍然是 UILabel 中的一个错误,它不会动画其大小变化。

与此同时,您可能需要问自己为什么要调整标签大小(例如,而不是将其放在其父级中)。

【讨论】:

谢谢。我刚刚使用了label.contentMode = UIViewContentModeCenter

以上是关于设备旋转时是不是有动画自动布局(约束)?的主要内容,如果未能解决你的问题,请参考以下文章

[iOS]:删除和添加约束时自动布局动画更改框架位置

自动旋转时自动布局约束更新

自动布局和设备旋转中到顶部的比例距离

UITableViewHeaderFooterView 不支持笔尖中的自动布局约束

如何设置自动布局约束常量通用或设备特定?

基于尺寸元素的设备旋转期间的动画更改将在旋转完成后进行