我有一个UIViewController,在设备旋转时只旋转其中的一些子视图。这在iOS7下运行良好,但在iOS8下出现问题。看起来在iOS8下,UIView的边界会受到变换的影响而发生调整。这是意料之外的。
以下是一些代码:
@interface VVViewController ()
@property (weak, nonatomic) IBOutlet UIView *pinnedControls;
@property (nonatomic, strong) NSMutableArray *pinnedViews;
@end
@implementation VVViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.pinnedViews = [NSMutableArray array];
[self.pinnedViews addObject:self.pinnedControls];
}
-(void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[UIViewController rotatePinnedViews:self.pinnedViews forOrientation:self.interfaceOrientation];
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation) && UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) {
[UIViewController rotatePinnedViews:self.pinnedViews forOrientation:toInterfaceOrientation];
}
}
@end
我们在UIViewController上创建了一个分类以处理此行为。以下是相关代码:
@implementation UIViewController (VVSupport)
+ (void)rotatePinnedViews:(NSArray *)views forOrientation:(UIInterfaceOrientation)orientation {
const CGAffineTransform t1 = [UIViewController pinnedViewTansformForOrientation:orientation counter:YES];
const CGAffineTransform t2 = [UIViewController pinnedViewTansformForOrientation:orientation counter:NO];
[views enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop) {
// Rotate the view controller
view.transform = t1;
[view.subviews enumerateObjectsUsingBlock:^(UIView *counterView, NSUInteger idx, BOOL *stop) {
// Counter-rotate the controlsUIin the view controller
counterView.transform = t2;
}];
}];
}
+ (CGAffineTransform)pinnedViewTansformForOrientation:(UIInterfaceOrientation)orientation counter:(BOOL)counter {
CGAffineTransform t;
switch ( orientation ) {
case UIInterfaceOrientationPortrait:
case UIInterfaceOrientationPortraitUpsideDown:
t = CGAffineTransformIdentity;
break;
case UIInterfaceOrientationLandscapeLeft:
t = CGAffineTransformMakeRotation(counter ? M_PI_2 : -M_PI_2);
break;
case UIInterfaceOrientationLandscapeRight:
t = CGAffineTransformMakeRotation(counter ? -M_PI_2 : M_PI_2);
break;
}
return t;
}
@end
这是 nib 的样子:
IBOutlet pinnedControls 对应着 nib 中被命名为 pinned 的 UIView:
在 iOS7 或 iOS8 竖屏模式下,结果如下图所示:
而在 iOS7 横屏模式下,结果如下图所示:
但是,在 iOS8 (GM) 下没有这种行为。相反,我看到的是这样的:
请注意,“Pinned Label” 文字的 UILabel 中心与未改变大小以适应旋转的 pinned UIView 底部的距离保持不变。该 UIView 的所有边沿都固定在超级视图的顶部、左侧、底部和右侧。
在 iOS8 下,它看起来似乎与 Auto Layout 互动方式不同。我有点困惑。我知道我不能依赖于 frame。我可能只会开始手动设置 bounds,但那似乎是错误的事情,实际上是绕过了 Auto Layout。