本文介绍了在 iOS8 下使用 CGAffineTransform 旋转时 UIView 不调整大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 UIViewController,它只在设备旋转时旋转其中的一些子视图.这在 iOS7 下可以正常工作,但在 iOS8 下会中断.看来UIView的边界是由iOS8下的变换调整的.这是出乎意料的.

I have a UIViewController that only rotates some of it subviews when the device is rotated. This works fine under iOS7 but breaks under iOS8. It appears that the UIView's bounds are adjusted by the transform under iOS8. This was unexpected.

这里有一些代码:

@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 上创建了一个类别来处理这种行为.以下是相关代码:

We've made a category on UIViewController to handle this behavior. Here's the pertinent code:

@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:

The UIView named pinned in the nib is the IBOutlet of pinnedControls:

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

When I run this in portrait mode under iOS7 or iOS8 I get this:

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

And I see the desired outcome under iOS7 in landscape mode:

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

But under iOS8 (GM) I do not get this behavior. This is what I see instead:

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

Notice that the center of the UILabel with the text "Pinned Label" is maintaining its distance from the bottom of the pinned UIView, which has not changed size to accommodate the rotation. That UIView has all its edges pinned to the top, left, bottom and right sides of the super view.

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

It looks to me that the transform property interacts with Auto Layout differently under iOS8. I'm a bit baffled here. I know I can't rely on the frame. I may just start manually setting bounds but that just seems like the wrong thing to do, essentially do an end run around Auto Layout.

推荐答案

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

This is more of a work around than a fix so it may not help everybody in similar situations. My problem was that the outer "pinned" view was being resized again after the transform was applied.

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

My solution was to change the constraints on the pinned view to be center vertically, center horizontally, and width and height equal a constant.

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

Then, in viewDidLoad, I set the height and width of the pinned view's frame to be the height of the main screen. This makes the view square so I don't care if it gets an extra rotate.

这篇关于在 iOS8 下使用 CGAffineTransform 旋转时 UIView 不调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 01:17