[英]Auto layout, screen rotation and UIView animation
我遇到了一個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>>'
違規觀點是自我觀點。
我如何創建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];
}];
代碼在旋轉時是否與頂部和底部混淆了? 是否認為肖像頂部是景觀的左側?
好的,我找到了解決方案。 它沒有解決上述問題,而是找到另一種方法來解決它。
我將約束改為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的缺點。
對於從谷歌來到這里的任何人:我在我的自定義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應用程序)你不應該執行這樣的調用,所以我刪除它,現在一切正常
你是對的,自動布局不適用於影響UI對象的對齊矩形的動畫變換。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.