自动布局、屏幕旋转和 UIView 动画

Auto layout, screen rotation and UIView animation(自动布局、屏幕旋转和 UIView 动画)

本文介绍了自动布局、屏幕旋转和 UIView 动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个 UIView 的问题,我将它添加到屏幕底部并在按下按钮时将其动画化以填充大部分屏幕.视图将上下动画并按预期旋转.如果我尝试在横向设置动画,它会中断并给我错误消息:

I am having an issue with a UIView that I add to the the bottom of the screen and animate it up to fill most of the screen if a button is pressed. The view will animate up and down and rotates as intended. If I try to animate while in landscape, it breaks and gives me error message:

*** Assertion failure in -[UIScrollView _edgeExpressionInContainer:vertical:max:], /SourceCache/UIKit_Sim/UIKit-2380.17/NSLayoutConstraint_UIKitAdditions.m:2174
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Autolayout doesn't support crossing rotational bounds transforms with edge layout constraints, such as right, left, top, bottom. The offending view is: <UIView: 0x9199340; frame = (20 0; 748 1024); transform = [0, -1, 1, 0, 0, 0]; autoresize = RM+BM; layer = <CALayer: 0x91993d0>>'

有问题的视图是 self.view.

The offending view is self.view.

我如何创建 UIView:

How I create the UIView:

[self.myContentView addSubview:subBar.filterListView];

[self.myContentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[filterListView]|"
                                                                           options:0
                                                                           metrics:nil
                                                                             views:@{@"filterListView": subBar.filterListView}]];

subBar.filterListView.bottomConstraint = [NSLayoutConstraint constraintWithItem:subBar.filterListView
                                                                      attribute:NSLayoutAttributeBottom
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:self.mapView
                                                                      attribute:NSLayoutAttributeBottom
                                                                     multiplier:1
                                                                       constant:0];

subBar.filterListView.topConstraint = [NSLayoutConstraint constraintWithItem:subBar.filterListView
                                                                   attribute:NSLayoutAttributeTop
                                                                   relatedBy:NSLayoutRelationEqual
                                                                      toItem:self.mapView
                                                                   attribute:NSLayoutAttributeBottom
                                                                  multiplier:1
                                                                    constant:0];

[self.myContentView addConstraint:subBar.filterListView.bottomConstraint];
[self.myContentView addConstraint:subBar.filterListView.topConstraint];

self.myContentView 是一个占据了整个 self.view 的 UIView:

self.myContentView is a UIView that takes up the whole self.view:

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView]|"
                                                                  options:0
                                                                  metrics:nil
                                                                    views:NSDictionaryOfVariableBindings(contentView)]];

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|"
                                                                         options:0
                                                                         metrics:nil
                                                                           views:NSDictionaryOfVariableBindings(contentView)]];    

要为 subBar.filterListView 设置动画,我删除了顶部和底部约束,重新分配它们,添加它们,然后设置动画:

To animate the the subBar.filterListView, i remove the top and bottom constrain, reassign them, add them, and animate:

[self.myContentView removeConstraint:view.topConstraint];
[self.myContentView removeConstraint:view.bottomConstraint];

view.topConstraint = [NSLayoutConstraint constraintWithItem:view
                                                  attribute:NSLayoutAttributeTop
                                                  relatedBy:NSLayoutRelationEqual
                                                     toItem:self.topToolBar
                                                  attribute:NSLayoutAttributeBottom
                                                 multiplier:1
                                                   constant:0];

view.bottomConstraint.constant -= SUB_BAR_SIZE.height;

[self.myContentView addConstraint:view.topConstraint];
[self.myContentView addConstraint:view.bottomConstraint];

[self.myContentView setNeedsUpdateConstraints];

[UIView animateWithDuration:.25 animations:^{
    [self.myContentView layoutIfNeeded];
}];

代码在旋转时会与顶部和底部混淆吗?它认为肖像的顶部是风景的左边吗?

Is the code getting confused with top and bottom when it rotates? Does it think the portrait top is the landscape's left?

推荐答案

好的,我找到了解决方案.它并没有解决上述问题,而是找到了另一种解决方法.

Ok, I found a solution. It doesn't fix the above issue, but rather found another way to approach it.

我将约束改为可视格式语言 (VFL) 方法:

I changed my constraints to the Visual Format Language (VFL) method instead:

subBar.filterListView.verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[filtersSubBar][filterListView(0)]" options:0
                                                                                    metrics:nil
                                                                                      views:@{@"filterListView": subBar.filterListView, @"filtersSubBar" : subBar.filtersSubBar}];

我认为问题在于使用导致问题的属性 NSLayoutAttributeTopNSLayoutAttributeRight 等.

I think the issue was using the attributes NSLayoutAttributeTop, NSLayoutAttributeRight, etc that was causing the issue.

Autolayout 无法处理旋转并尝试使用 NSLayoutAttributeTop 而应该将其更改为 NSLayoutAttributeRight 来表达新的方向.我想我们可以手动更改约束.

Autolayout couldn't handle the rotation and trying to use the NSLayoutAttributeTop when it should have been changed to NSLayoutAttributeRight to express the new orientation. I suppose we could manually change the constraint.

似乎 VFL 处理它的方式不同并且不使用属性?

It seems the VFL handles it differently and does not use the attributes?

这感觉好像它要么是一个错误,要么只是 iOS 的一个缺点.

This feels as if its either a bug or just a shortcoming of iOS.

这篇关于自动布局、屏幕旋转和 UIView 动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:自动布局、屏幕旋转和 UIView 动画

基础教程推荐