【问题标题】:UIView not resizing when rotated with a CGAffineTransform under iOS8在 iOS8 下使用 CGAffineTransform 旋转时 UIView 不调整大小
【发布时间】:2014-10-23 21:52:10
【问题描述】:

我有一个 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

这是笔尖的样子:

nib中名为pinned的UIView是pinnedControls的IBOutlet:

当我在 iOS7 或 iOS8 下以纵向模式运行时,我得到了这个:

我在横屏模式下的 iOS7 下看到了预期的结果:

但在 iOS8 (GM) 下我没有这种行为。这就是我所看到的:

请注意,带有文本“Pinned Label”的 UILabel 的中心与固定 UIView 的底部保持距离,它没有改变大小以适应旋转。该 UIView 的所有边缘都固定在超级视图的顶部、左侧、底部和右侧。

在我看来,transform 属性在 iOS8 下与 Auto Layout 的交互方式不同。我在这里有点困惑。我知道我不能依赖框架。我可能只是开始手动设置边界,但这似乎是错误的做法,本质上是围绕自动布局进行结束运行。

【问题讨论】:

标签: autolayout ios8 cgaffinetransform


【解决方案1】:

所以在过去的几天里这让我发疯了,我可以通过在我的动画块中更改 setTransform 调用的时间来解决

在横向设置时,我在设置新框架后设置变换。拍摄肖像时,我在设置新框架之前设置变换。所有这些都在“animateWithDuration...”方法的动画块中进行

我不确定它是否会直接帮助您处理代码,但它可能会激发一些灵感来解决它,因为我们肯定遇到了类似的问题

【讨论】:

    【解决方案2】:

    这更像是一种变通方法而不是修复方法,因此它可能无法帮助处于类似情况的每个人。我的问题是,在应用转换后,外部“固定”视图再次调整大小。

    我的解决方案是将固定视图上的约束更改为垂直居中,水平居中,并且宽度和高度等于一个常数。

    然后,在 viewDidLoad 中,我将固定视图框架的高度和宽度设置为主屏幕的高度。这使得视图呈方形,所以我不在乎它是否得到额外的旋转。

    【讨论】:

      【解决方案3】:

      在 ios8 中,uiviewcontroller 需要根据设备方向使用 uitraitcollections 调整大小。否则,当您尝试旋转它时,您会在纵向模式下获得 uiview,而手机是横向的。所以正确的步骤是旋转并覆盖 uitraitcollections

      编辑: 我用以下代码覆盖我的 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 则它不起作用:'(

      【讨论】:

      • 有趣。我们的应用程序有几个 iOS8 视觉异常,它们还没有进入我的待办事项列表的顶部,但当它们出现时我肯定会记住这一点。顺便说一句,你覆盖 UITraitCollections 做什么?
      • 我覆盖了 uitraitcollections,因此视图被重新调整为横向,否则当您尝试手动旋转视图时保持纵向
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多