2013-02-28 75 views
1

我遇到了一个UIView问题,我将它添加到屏幕底部并将其动画化,以便在按下按钮时填充大部分屏幕。视图将上下移动并按预期旋转。如果我尝试在景观动画,同时,它打破了,给我的错误信息:自动布局,屏幕旋转和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是一个UIView,占用了整个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,我删除顶部和底部约束,重新分配它们,添加它们并生成动画:

[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]; 
}]; 

代码getti ng在旋转时与顶部和底部混淆?它是否认为肖像顶部是风景的左侧?

回答

2

好的,我找到了一个解决方案。它没有解决上述问题,而是找到了另一种方法来处理它。

我改变了我的约束,以视觉格式语言(VFL)方法:

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

我认为这个问题是使用属性NSLayoutAttributeTopNSLayoutAttributeRight等是造成这一问题。

Autolayout无法处理旋转,并尝试使用NSLayoutAttributeTop,此时应将其更改为NSLayoutAttributeRight以表示新方向。我想我们可以手动更改约束。

看来VFL处理它的方式不同,不使用属性?

这感觉就好像它不是iOS的缺陷就是缺点。

0

你说得对,Auto Layout不能处理影响UI对象对齐矩形的动画转换。

1

要有人来这里从谷歌:

@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]; 
我而在我的自定义调用presentView控制器PushSegue有此异常

(这是我的第一个iOS应用程序) 你不应该执行这样的调用,所以我删除它,现在一切正常