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

时间:2015-02-20 09:00:20

标签: ios objective-c uiviewcontroller ios8 uiwindow

我知道这看起来像一个很大的问题,但并非如此。害怕读它。主要是我解释了这些东西的运作方式。

我的应用中有两个UIWindow个。第一个是默认情况下应用程序创建的主窗口。第二个名为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];

这很好用,我在orientationChanged方法中呈现了横向视图控制器。一切都很顺利。如果我旋转回肖像,我会再次点击orientationChanged,此时我会关闭横向视图控制器。

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

app委托有两种方法,如下所示:

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

- (void)modalTransitionFinished:(NSNotification *)notif
{
    self.modalWindow.hidden = YES;
    self.modalWindow.rootViewController = nil;
}

我通过presentActivityOnModalWindow致电[[[UIApplication sharedApplication] delegate] performSelector....]。我知道这不是最好的做法,但它运作正常。关于解雇,我使用NSNotificationCenter发布关于解雇的通知。在modalWindow上显示的视图控制器仅支持纵向模式。它正在YESshouldAutorotateUIInterfaceOrientationMaskPortraitsupportedInterfaceOrientations返回。

很多解释但是现在我们遇到了问题。当我旋转到横向时,弹出modalWindow,关闭模态窗口并旋转回到肖像我的主窗口仍处于横向模式,一切看起来都是灾难性的。

我尝试向windowmodalWindow添加观察者并记录framebounds中的更改,结果如下:

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

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

3 个答案:

答案 0 :(得分:1)

系统只会处理keyWindow的轮播。如果你有其他窗户,你必须自己处理轮换。

我还认为模态控制器是可行的方法。但如果你真的想要处理轮换,请看看其他"自定义窗口"库处理旋转。警报视图就是一个很好的例子:

https://github.com/search?o=desc&q=uialertview&s=stars&type=Repositories&utf8=

答案 1 :(得分:0)

Apple不鼓励以这种方式使用Windows。最好使用模态显示的UIViewController代替

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

使用

UIViewController实例以模态方式呈现UIViewController
[self presentViewController:<#(UIViewController *)#> animated:<#(BOOL)#> completion:<#^(void)completion#>]

答案 2 :(得分:-1)

您正在创建2个窗口,Apple建议不要这样做。应用程序应该拥有与显示设备一样多的窗口。(SEE UIWindow reference

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

或者,您可以使用1个视图并在方向更改时进行调整。这样做的难易程度取决于所显示信息的类型。 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视图方法可能是最简单的。

[如果以上解决方案不适合您,可能会提供有关2个屏幕上显示的数据差异的更多信息。 欢呼声。]