我遇到了一个UIView的问题,我添加到屏幕底部并设置动画以填充大部分屏幕(如果按下按钮)。视图将上下动画并按预期旋转。如果我尝试在横向中制作动画,它会中断并给出错误消息:
*** 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。
我如何创建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.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设置动画,我会移除顶部和底部约束,重新分配它们,添加它们并设置动画:
[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];
}];
代码在旋转时是否与顶部和底部混淆了?是否认为肖像顶部是景观的左侧?
答案 0 :(得分:2)
好的,我找到了解决方案。它没有解决上述问题,而是找到另一种方法来解决它。
我改为将约束改为Visual Format Language(VFL)方法:
subBar.filterListView.verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[filtersSubBar][filterListView(0)]" options:0
metrics:nil
views:@{@"filterListView": subBar.filterListView, @"filtersSubBar" : subBar.filtersSubBar}];
我认为问题是使用导致问题的NSLayoutAttributeTop
,NSLayoutAttributeRight
等属性。
Autolayout无法处理轮换并尝试使用NSLayoutAttributeTop
时应将其更改为NSLayoutAttributeRight
以表达新方向。我想我们可以手动更改约束。
似乎VFL以不同的方式处理它并且不使用属性?
这感觉好像它只是一个bug或只是iOS的缺点。
答案 1 :(得分:1)
对于从谷歌来到这里的任何人:我在自定义PushSegue中调用presentView控制器时遇到此异常:
@implementation PushSegue
- (void) perform
{
UIViewController* fromController = (UIViewController*) self.sourceViewController;
UIViewController* toController = (UIViewController*) self.destinationViewController;
CATransition* transition = [CATransition animation];
BOOL iPad = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad;
transition.duration = iPad ? 0.5 : 0.3;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
switch ([UIApplication sharedApplication].statusBarOrientation)
{
case UIInterfaceOrientationPortraitUpsideDown:
transition.subtype = kCATransitionFromLeft;
break;
case UIInterfaceOrientationLandscapeLeft:
transition.subtype = kCATransitionFromBottom;
break;
case UIInterfaceOrientationLandscapeRight:
transition.subtype = kCATransitionFromTop;
break;
default:
transition.subtype = kCATransitionFromRight;
break;
}
[fromController.view.window.layer addAnimation:transition forKey:nil];
[fromController presentViewController:toController animated:NO completion:nil];
}
@end
原因是我的代码中出现了一些误解:
[self.view setTranslatesAutoresizingMaskIntoConstraints:NO];
(这是我的第一个ios应用程序) 你不应该执行这样的调用,所以我删除它,现在一切正常
答案 2 :(得分:0)
你是对的,自动布局不适用于影响UI对象的对齐矩形的动画变换。