如何防止UIWindow视图自动旋转

时间:2014-10-02 17:30:26

标签: ios objective-c cocoa-touch uiwindow auto-rotation

我有一个名为OoviumController的UIViewController响应设备轮换。 OoviumController是我的应用程序的UIWindow rootViewController。 UIWindow也是它自己的观点。 OoviumController的视图是透明的,位于UIWindow视图的顶部,该视图不应旋转。

从iOS 2到iOS 7,这一切都运行良好。但是,我正在尝试使用XCode 6 for iOS 8构建我的项目,我注意到现在除了OoviumController的视图外,UIWindow视图也在旋转,这导致我的应用程序出现严重问题。

如何将功能恢复到以前的工作方式?如何阻止UIWindow与我的rootViewController视图一起旋转?

我还注意到UIWindow文档不再将其列为继承UIView,即使addSubview似乎仍然有用。这是文档错误还是UIView的公共继承被弃用了?

2 个答案:

答案 0 :(得分:0)

我还没有找到一个快速,简单或优雅的解决方案来解决这个问题。然而,我找到了一个乏味的蛮力解决方案。我几个月前就开始工作,实际上并不认为我已经完成了。但是,我会为任何感兴趣的人发布基本的框架工作。

基本概念是创建两个UIWindow对象,一个旋转,另一个不旋转。然后在旋转开始之前将所有控件从旋转窗口翻转到非旋转窗口。旋转完成后将其翻转:

- (void) hideHovers {
    for (Hover* hover in self.hovers)
        hover.alpha = 0;
}
- (void) showHovers {
    for (Hover* hover in self.hovers)
        hover.alpha = 1;
}

// Public ==========================================================================================
- (void) addHover:(Hover*)hover {
    [[Oovium aetherWindow] addSubview:hover];
    [self.hovers addObject:hover];
}

- (void) beforeRotation {
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    for (Hover* hover in self.hovers) {
        hover.orientation = orientation;
        [hover removeFromSuperview];
        [controlWindow_ addSubview:hover];
    }
    controlWindow_.hidden = NO;
    [self showHovers];
    [UIView animateWithDuration:0.5 animations:^{
        [self hideHovers];
    }];
}
- (void) afterRotation {
    for (Hover* hover in self.hovers) {
        hover.transform = CGAffineTransformIdentity;
        [hover removeFromSuperview];
        [[Oovium aetherWindow] addSubview:hover];
        [hover place];
    }
    controlWindow_.hidden = YES;
    [UIView animateWithDuration:0.5 animations:^{
        [self showHovers];
    }];
}

实际上,这很容易。困难的部分是处理控件的转换。以下代码并非完全适用于所有轮换。我完成后会修改它,但我不确定何时能够恢复它。

//
//  Hover.m
//  Oovium
//
//  Created by Joe Charlier on 2/22/15.
//  Copyright (c) 2015 Aepryus Software. All rights reserved.
//

#import "Controls.h"
#import "Hover.h"
#import "Oovium.h"
#import "Utility.h"

@interface Hover ()

@property (nonatomic) OOAnchor anchor;
@property (nonatomic) CGPoint offset;
@property (nonatomic) CGSize size;

@end

@implementation Hover

// Static ==========================================================================================
static CGPoint points_[5][5];
static CGPoint shift_[5];

+ (void) initialize {
    CGFloat width = [Utility deviceBounds].size.width;
    CGFloat height = [Utility deviceBounds].size.height;

    CGPoint topLeft = CGPointMake(0,0);
    CGPoint topRight = CGPointMake(width,0);
    CGPoint bottomLeft = CGPointMake(0,height);
    CGPoint bottomRight = CGPointMake(width,height);
    CGPoint center = CGPointMake(width/2,height/2);

    points_[UIInterfaceOrientationPortrait][OOAnchorTopLeft] = topLeft;
    points_[UIInterfaceOrientationPortrait][OOAnchorTopRight] = topRight;
    points_[UIInterfaceOrientationPortrait][OOAnchorBottomLeft] = bottomLeft;
    points_[UIInterfaceOrientationPortrait][OOAnchorBottomRight] = bottomRight;
    points_[UIInterfaceOrientationPortrait][OOAnchorCenter] = center;

    points_[UIInterfaceOrientationLandscapeRight][OOAnchorTopLeft] = topRight;
    points_[UIInterfaceOrientationLandscapeRight][OOAnchorTopRight] = bottomRight;
    points_[UIInterfaceOrientationLandscapeRight][OOAnchorBottomLeft] = topLeft;
    points_[UIInterfaceOrientationLandscapeRight][OOAnchorBottomRight] = bottomLeft;
    points_[UIInterfaceOrientationLandscapeRight][OOAnchorCenter] = center;

    points_[UIInterfaceOrientationPortraitUpsideDown][OOAnchorTopLeft] = bottomRight;
    points_[UIInterfaceOrientationPortraitUpsideDown][OOAnchorTopRight] = bottomLeft;
    points_[UIInterfaceOrientationPortraitUpsideDown][OOAnchorBottomLeft] = topRight;
    points_[UIInterfaceOrientationPortraitUpsideDown][OOAnchorBottomRight] = topLeft;
    points_[UIInterfaceOrientationPortraitUpsideDown][OOAnchorCenter] = center;

    points_[UIInterfaceOrientationLandscapeLeft][OOAnchorTopLeft] = bottomLeft;
    points_[UIInterfaceOrientationLandscapeLeft][OOAnchorTopRight] = topLeft;
    points_[UIInterfaceOrientationLandscapeLeft][OOAnchorBottomLeft] = bottomRight;
    points_[UIInterfaceOrientationLandscapeLeft][OOAnchorBottomRight] = topRight;
    points_[UIInterfaceOrientationLandscapeLeft][OOAnchorCenter] = center;

    shift_[OOAnchorTopLeft] = CGPointMake(0, 0);
    shift_[OOAnchorTopRight] = CGPointMake(1, 0);
    shift_[OOAnchorBottomLeft] = CGPointMake(0, 1);
    shift_[OOAnchorBottomRight] = CGPointMake(1, 1);
    shift_[OOAnchorCenter] = CGPointMake(0.5, 0.5);
}
// =================================================================================================

+ (CGRect) placeInRect:(CGRect)rect anchor:(OOAnchor)anchor offset:(CGPoint)offset size:(CGSize)size {
    CGPoint shift = shift_[anchor];
    CGFloat x = shift.x*(rect.size.width-size.width)+offset.x;
    CGFloat y = shift.y*(rect.size.height-size.height)+offset.y;
    return CGRectMake(x, y, size.width, size.height);
}

- (id) initWithAnchor:(OOAnchor)anchor offset:(CGPoint)offset size:(CGSize)size {
    if (self = [super initWithFrame:[Hover placeInRect:[UIScreen mainScreen].bounds anchor:anchor offset:offset size:size]]) {
        self.anchor = anchor;
        self.offset = offset;
        self.size = size;
        self.backgroundColor = [UIColor purpleColor];
    }
    return self;
}

- (void) setOrientation:(UIInterfaceOrientation)orientation {
    _orientation = orientation;

    CGPoint aO = self.frame.origin;
    CGPoint aN = points_[orientation][_anchor];

    double w = self.size.width;
    double h = self.size.height;
    double q = (self.size.height-self.size.width)/2;
    double ox = self.offset.x;
    double oy = self.offset.y;
    double ax = aN.x-aO.x;
    double ay = aN.y-aO.y;

    double dx=0;
    double dy=0;
    if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) {
        dx += q;
        dy += q;
    }
    switch (orientation) {
        case UIInterfaceOrientationPortrait:
            dx = 0;
            dy = 0;
            break;
        case UIInterfaceOrientationPortraitUpsideDown:
            switch (_anchor) {
                case OOAnchorTopLeft:
                    dx += -ax+w+ox;
                    dy += -ay+h+oy;
                    break;
                case OOAnchorTopRight:
                    dx += -ax+ox;
                    dy += -ay+h+oy;
                    break;
                case OOAnchorBottomLeft:
                    dx += -ax+w+ox;
                    dy += -ay+oy;
                    break;
                case OOAnchorBottomRight:
                    dx += -ax+ox;
                    dy += -ay+oy;
                    break;
            }
            break;
        case UIInterfaceOrientationLandscapeRight:
            switch (_anchor) {
                case OOAnchorTopLeft:
                    dx += 0;
                    dy += ax-h-ox;
                    break;
                case OOAnchorTopRight:
                    dx += -ay+w+oy;
                    dy += ax-h+ox;
                    break;
                case OOAnchorBottomLeft:
                    dx += -ay+oy;
                    dy += 0;
                    break;
                case OOAnchorBottomRight:
                    dx += -ay+w-oy;
                    dy += ax-ox;
                    break;
            }
            break;
        case UIInterfaceOrientationLandscapeLeft:
            switch (_anchor) {
                case OOAnchorTopLeft:
                    dx += ay-h-oy;
                    dy += -w;
                    break;
                case OOAnchorTopRight:
                    dx += -w;
                    dy += -ax-w-ox;
                    break;
                case OOAnchorBottomLeft:
                    dx += ay-h+oy;
                    dy += -ay-h;
                    break;
                case OOAnchorBottomRight:
                    dx += ay-w-oy;
                    dy += -ax+w-ox;
                    break;
            }
            break;
    }

    CGFloat angle = 0;
    switch (orientation) {
        case UIInterfaceOrientationPortrait:            angle = 0;          break;
        case UIInterfaceOrientationLandscapeRight:      angle = M_PI_2*3;   break;
        case UIInterfaceOrientationPortraitUpsideDown:  angle = M_PI;       break;
        case UIInterfaceOrientationLandscapeLeft:       angle = M_PI_2;     break;
        case UIInterfaceOrientationUnknown:break;
    }

    [self setTransform:CGAffineTransformConcat(
        CGAffineTransformMakeTranslation(dx,dy),
        CGAffineTransformMakeRotation(angle)
     )];
}

- (void) invoke {
    [[Oovium controls] invoke:self];
}

- (void) place {
    CGSize sz = [UIScreen mainScreen].bounds.size;
    CGPoint shift = shift_[self.anchor];
    CGFloat x = shift.x*(sz.width-self.size.width)+self.offset.x;
    CGFloat y = shift.y*(sz.height-self.size.height)+self.offset.y;
    self.frame = CGRectMake(x, y, self.size.width, self.size.height);
}

@end

答案 1 :(得分:0)

我最近感觉到阻止轮换以获得额外应用窗口的冲动,现在找到了解决方案......

从iOS 6开始,UIApplicationDelegate支持以下方法:

- (UIInterfaceOrientationMask)application:(UIApplication *)application 
  supportedInterfaceOrientationsForWindow:(UIWindow *)window;

在这里,您可以返回窗口允许的方向,而不必处理可以恢复系统旋转的黑客攻击。

https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623107-application?language=objc