我有一个名为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的公共继承被弃用了?
答案 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;
在这里,您可以返回窗口允许的方向,而不必处理可以恢复系统旋转的黑客攻击。