Ios UIWindow方向问题(两个UIWindow和横向模式)

Ios UIWindow方向问题(两个UIWindow和横向模式),ios,objective-c,uiviewcontroller,ios8,uiwindow,Ios,Objective C,Uiviewcontroller,Ios8,Uiwindow,我知道这看起来是一个巨大的问题,但其实并不是这样,不要害怕读它。主要是我在解释东西是如何工作的 我的应用程序中有两个ui窗口s。第一个窗口是应用程序默认创建的主窗口。第二个称为modalWindow,也是在app委托中创建的 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWind

我知道这看起来是一个巨大的问题,但其实并不是这样,不要害怕读它。主要是我在解释东西是如何工作的

我的应用程序中有两个
ui窗口
s。第一个窗口是应用程序默认创建的主窗口。第二个称为
modalWindow
,也是在app委托中创建的

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.


    self.modalWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.modalWindow.windowLevel = UIWindowLevelStatusBar;

    //Other stuff I need
    //....

    return YES;
}
我的大多数应用程序都是纵向的,但是有一个视图控制器,用户可以在其中切换到横向。我正在通过以下途径收听景观变化:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
这工作得很好,在
方向更改
方法中,我展示了横向视图控制器。在这一点上一切都很好。如果我旋转回纵向,我会再次触发
方向更改
,此时我会关闭横向视图控制器

现在,让我们解释一下第二个窗口是如何发挥作用的。在横向模式下,有一个动作(只需按下一个按钮)在第二个窗口(modalWindow
)上显示一个新的视图控制器。好的,让我们解释一下

应用程序委托有两种方法,如下所示:

- (void)presentActivityOnModalWindow:(UIViewController *)viewController
{
    self.modalWindow.rootViewController = viewController;
    self.modalWindow.hidden = NO;
}

- (void)modalTransitionFinished:(NSNotification *)notif
{
    self.modalWindow.hidden = YES;
    self.modalWindow.rootViewController = nil;
}
我通过
[[[UIApplication sharedApplication]委托]性能选择器调用
在ModalWindow上的PresentActivity
。我知道这不是最好的做法,但效果很好。至于解雇,我使用通知中心发布解雇通知。在
modalWindow
上显示的视图控制器仅支持纵向模式。它在
shouldAutorotate
中返回
YES
,在
支持的接口方向中返回
UIInterfaceOrientationMaskPortrait

好了,我解释了很多,但现在我们开始讨论问题了。当我旋转到横向时,弹出模态窗口,关闭模态窗口并旋转回纵向。我的主窗口仍然处于横向模式,一切看起来都很糟糕

我尝试在
窗口
模型窗口
中添加一个观察者,并记录
边界
中的更改,结果如下:

Did finish launching:
window frame {{0, 0}, {320, 568}}
window bounds {{0, 0}, {320, 568}}
modalWindow frame {{0, 0}, {320, 568}}
modalWindow bounds {{0, 0}, {320, 568}}

Rotate to landscape:
window frame {{0, 0}, {568, 320}}

Open activity in landscape:
modalWindow frame {{0, 0}, {320, 568}}
modalWindow frame {{0, 0}, {320, 568}}

Dismiss activity:
none


Rotate back to portrait:
none

因此,当我们回到纵向模式时,我的
窗口
似乎无法恢复到正常帧如何解决此问题?如果我需要提供更多详细信息,请随时询问。

您正在创建2个windows,苹果建议不要这样做。应用程序的窗口数应与显示设备的数量相同。()

我建议使用2个视图,并根据方向在这些视图上“绘制”所有内容。然后在显示另一个视图时隐藏其中一个视图

或者,您可以只使用一个视图,并在方向更改时进行调整。执行此操作的难易程度取决于显示的信息类型。 方向更改最好由AppDelegate代码检测

下面是我用来检测方向变化的代码示例,然后检查窗口的新尺寸

- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation
{

    //other stuff from rotate:
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];

    CGRect appFrame = [[UIScreen mainScreen ]applicationFrame];//using frame so status bar is not part of calculations.

    if (orientation == UIInterfaceOrientationLandscapeRight
        ||
        orientation == UIInterfaceOrientationLandscapeLeft
        )
    {
        self.currentAppScreenWidth  = appFrame.size.height;
        self.currentAppScreenHeight = appFrame.size.width;
        [YOURapp reArrangeSubViews_and_Layouts: appFrame];//Something like this - maybe.
    }
    else
    {
        self.currentAppScreenWidth = appFrame.size.width;
        self.currentAppScreenHeight = appFrame.size.height;
        [YOURapp reArrangeSubViews_and_Layouts: appFrame];//Something like this - maybe.

     }
}
希望有帮助。 还有一件事。如果使用不同的布局显示相同的信息,那么应该能够使用Xcode工具进行布局,以便以合适的方式适应方向。如果某些事情仍然不完美,那么尝试使用代码进行调整。 如果显示的信息完全不同,那么2视图方法可能是最简单的

[如果上述解决方案不适用于您,可能需要更多关于两个屏幕上显示的数据差异的信息。
干杯。]

系统将只处理
键窗口的旋转。如果您有其他窗口,则必须自己处理旋转

我还认为模态控制器是一条可行之路。但是,如果您真的想处理旋转,请查看其他“自定义窗口”库如何处理旋转。警报视图就是一个很好的例子:


苹果不鼓励以这种方式使用windows。最好使用模式显示的
UIViewController
代替您的

self.modalWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
通过
UIViewController
实例,使用

[self presentViewController:<#(UIViewController *)#> animated:<#(BOOL)#> completion:<#^(void)completion#>]
[自我呈现视图控制器:动画:完成:]