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

6

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

我的应用程序中有两个UIWindow。第一个是默认情况下由应用程序创建的主窗口。第二个称为modalWindow,也是在应用程序委托中创建的。

- (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)上呈现一个新的视图控制器。好的,让我们来解释一下。
应用程序委托有两种方法,如下所示:
- (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] delegate] performSelector....]调用presentActivityOnModalWindow。我知道这不是最佳实践,但它可以正常工作。至于关闭,我使用NSNotificationCenter发布有关关闭的通知。在modalWindow上呈现的视图控制器仅支持纵向模式。它在shouldAutorotate中返回YES,并在supportedInterfaceOrientations中返回UIInterfaceOrientationMaskPortrait
好的,解释了很多,现在我们来到问题。当我旋转到横向、弹出modalWindow、关闭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个回答

1

0

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

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

以模态方式展示一个UIViewController是从UIViewController实例中使用完成的

[self presentViewController:<#(UIViewController *)#> animated:<#(BOOL)#> completion:<#^(void)completion#>]

-1

您正在创建2个窗口,但Apple不建议这样做。一个应用程序应该有与显示设备一样多的窗口。(请参阅UIWindow参考)

我建议使用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工具进行布局,以适应合适的方向。如果某些事情仍然不完美,请尝试使用代码进行微调。 如果您显示完全不同的信息,则采用两个视图的方法可能是最简单的。
[如果上述解决方案对您不起作用,请提供有关在两个屏幕上显示的数据差异的更多信息。 干杯。]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接