我有一个UIViewController,它只在旋转设备时旋转一些子视图。这在iOS7下工作正常但在iOS8下有所不同。似乎UIView的界限是通过iOS8下的变换来调整的。这是出乎意料的。
以下是一些代码:
@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
这是笔尖的样子:
在笔尖中固定的UIView是pinnedControls的IBOutlet:
当我在iOS7或iOS8下以纵向模式运行时,我得到了这个:
我在横向模式下看到iOS7下的预期结果:
但是在iOS8(GM)下我没有这种行为。这就是我所看到的:
请注意,带有“固定标签”文本的UILabel中心与固定UIView的底部保持距离,UIView的尺寸没有改变以适应旋转。 UIView的所有边缘都固定在超视图的顶部,左侧,底部和右侧。
在我看来,转换属性在iOS8下与Auto Layout的交互方式不同。我在这里有点困惑。我知道我不能依赖这个框架。我可能只是开始手动设置边界,但这似乎是错误的事情,基本上是围绕自动布局结束。
答案 0 :(得分:1)
所以这让我疯狂了过去几天,我能够通过改变动画块中setTransform调用的时间来解决这个问题
进入风景时,我在设置新帧后设置了转换。当我去画像时,我在设置新画面之前设置了变换。所有这一切都发生在" animateWithDuration的动画块内......"方法
我不确定它是否会直接帮助您使用您的代码,但它可能会激发一些灵感来解决它,因为我们肯定有类似的问题
答案 1 :(得分:0)
这更像是一个解决方案,而不是一个修复,所以它可能无法帮助处于类似情况的每个人。我的问题是在应用转换后,外部“固定”视图再次调整大小。
我的解决方案是将固定视图上的约束更改为垂直居中,水平居中,宽度和高度等于常量。
然后,在viewDidLoad中,我将固定视图框架的高度和宽度设置为主屏幕的高度。这使视图变得方正,所以我不在乎它是否有额外的旋转。
答案 2 :(得分:0)
编辑:
我使用以下代码覆盖我的uitraitcollection
UITraitCollection *horTrait = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
UITraitCollection *verTrait = [UITraitCollection traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact];
UITraitCollection *finalTrait = [UITraitCollection traitCollectionWithTraitsFromCollections:@[horTrait,verTrait]];
[self.parentViewController setOverrideTraitCollection:finalTrait forChildViewController:self];
不幸的是,如果我试图修改的uiviewcontroller没有parentviewcontroller,它就无法工作:'(