繁体   English   中英

iPad / iOS7:从中呈现“全屏”视图控制器后,“页面”模式视图控制器出现异常行为

[英]iPad/iOS7: 'Page' modal view controller strange behaviour after presenting 'Full screen' view controller from it

我的iPad应用程序以“页面”演示风格打开模式视图控制器。 如您所知,“页面”呈现样式不会覆盖呈现视图控制器以指示页面呈现的状态栏。

初始视图控制器

页面模式视图控制器

应用程序从模态视图控制器中打开UIImagePickerController进行照片制作。 UIImagePickerController具有“全屏”呈现样式。 解散图像选择器后,显示的模态视图控制器会变高20px,并且与初始视图控制器的状态栏重叠。

我试图用简单的UINavigationController替换UIImagePickerController ,它也破坏了我的模式视图控制器。

有屏幕截图: 全屏视图控制器

模态视图控制器损坏

恢复“页面”视图控制器大小的唯一方法是在返回“页面”视图控制器后更改viewController.view.superview.superview.superview.superview框架的高度。 但这真的很奇怪。

关闭嵌套模态视图控制器后,还有另一种方法可以修复“页面”模态视图控制器的显示吗?

更新:我使用了这样奇怪的代码来解决我的问题:

#define STATUS_BAR_HEIGHT 20
#define IPAD_PORTRAIT_HEIGHT 1004
#define IPAD_LANDSCAPE_HEIGHT 748
UIView *superview = nil;

// In case of this view controller included in navigationController we have to use superview of navigation's controller view
if (self.navigationController)
    superview = self.navigationController.view.superview;
else
    superview = self.view.superview;

CGRect r = superview.frame;

// Sometimes we have to fix height + origin, sometimes only height (becase view has bottom magnifying)
// In landscape orientation we have to fix 'width' instead of 'height', because that view controller always works in 'portrait' mode
if (self.interfaceOrientation == UIInterfaceOrientationPortrait && r.size.height > IPAD_PORTRAIT_HEIGHT) {
    r.origin.y = STATUS_BAR_HEIGHT;
    r.size.height = IPAD_PORTRAIT_HEIGHT;
}
else if (self.interfaceOrientation == UIInterfaceOrientationMaskPortraitUpsideDown && r.size.height > IPAD_PORTRAIT_HEIGHT) {
    r.size.height = IPAD_PORTRAIT_HEIGHT;
}
else if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft && r.size.width > IPAD_LANDSCAPE_HEIGHT) {
    r.size.width = IPAD_LANDSCAPE_HEIGHT;
    r.origin.x = STATUS_BAR_HEIGHT;
}
else if (self.interfaceOrientation == UIInterfaceOrientationLandscapeRight && r.size.width > IPAD_LANDSCAPE_HEIGHT) {
    r.size.width = IPAD_LANDSCAPE_HEIGHT;
}

superview.frame = r;

我不相信再没有优雅的解决方案了。 有什么想法可以改进吗?

UPDATE2:我刚刚打开一个错误。 您可以在此处关注它: rdar:// 15949644

UPDATE3:有我的示例项目: 链接

没有一个好的解决方案,这是一个Apple错误,在修复该错误之前,您必须解决它。 在iOS 7.1中尚未修复。 我为此设计了一个解决方案,并意识到我也在实现相同的解决方案。 很难看,但是可以用。

一句话就这个设计。 我猜为什么Apple忽略了这个问题是因为全屏显示视图控制器并不是Apple可以做的。 当然,这不是借口,有时候除了呈现全屏之外别无选择(例如,我们必须打开一个摄像机视图,例如,必须以全屏模式打开它)。 也许您可以更改设计以适应Apple的错误。

“确保呈现模态视图的ViewController在NavigationController中,并且这种怪异现象应该停止。”我的最初答案-错误

已更新这确实听起来像是个错误,尽管从用户体验的角度来看,您实际上并没有遇到任何问题。 呈现“页面”呈现样式的视图控制器,然后以全屏模式呈现另一个视图控制器似乎有点错误。

IMO从一开始就只是一个糟糕的设计,因此它没有按您预期的那样工作的事实可能是因为任何设置它的人都没有想到有人会那样使用它。

尽管最初的回答很简短,但我还是会将您模态呈现的视图控制器嵌入导航控制器中,然后将UIImagPickerViewController推入其中,或者将它的动画视图添加到您的视图中,好像它看起来像另一个页面样式的模态一样呈现视图。 如果那是您想要的影响。

所有这些听起来都不是完美的,更完美的解决方案是查看应用程序的流程,并可能重新评估事物的呈现方式。

我认为这是iOS7的一个问题,其中View的布局已稍有更改。 我在弹出模式自定义视图中遇到了类似的问题,在其中发现了相同的行为。 我通过在viewDidLoad添加这一行来解决

self.edgesForExtendedLayout = UIRectEdgeNone;

也许对您的问题有一些提示是有用的。

UIImagePicker(或更广泛地说,UINavigationController)肯定存在一个问题,即不遵循应用程序中的任何状态栏设置。

已经通过在UINavigationController委托中重新应用状态栏设置来讨论和解决此问题(请参阅UIImagePickerController中断状态栏外观 )。

在您的情况下,您可能要调用self.edgesForExtendedLayout = UIRectEdgeNone; 或尝试在委托回调中重置一些状态栏属性

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;

看起来这是一个iOS错误,目前可以通过这种解决方法解决(这是“页面”模式视图控制器的一种方法)

#define STATUS_BAR_HEIGHT 20
#define IPAD_PORTRAIT_HEIGHT 1004
#define IPAD_LANDSCAPE_HEIGHT 748

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear: animated];

    // In case of iOS7 we need this weird code, because after displaying full screen view controller from 'Page' modal view controller our 'Page' controller
    // incorrectly shifts 20px up
    //
    // I haven't found best solution for now
    // There is my question on SO: http://stackoverflow.com/questions/21146801/ipad-ios7-page-modal-view-controller-strange-behaviour-after-presenting-full
    if (!isIOS6()) {
        [self setNeedsStatusBarAppearanceUpdate];

        UIView *superview = nil;

        // In case of this view controller included in navigationController we have to use superview of navigation's controller view
        if (self.navigationController)
            superview = self.navigationController.view.superview;
        else
            superview = self.view.superview;

        CGRect r = superview.frame;

        // Sometimes we have to fix height + origin, sometimes only height (becase view has bottom magnifying)
        // In landscape orientation we have to fix 'width' instead of 'height', because that view controller always works in 'portrait' mode
        if (self.interfaceOrientation == UIInterfaceOrientationPortrait && r.size.height > IPAD_PORTRAIT_HEIGHT) {
            r.origin.y = STATUS_BAR_HEIGHT;
            r.size.height = IPAD_PORTRAIT_HEIGHT;
        }
        else if (self.interfaceOrientation == UIInterfaceOrientationMaskPortraitUpsideDown && r.size.height > IPAD_PORTRAIT_HEIGHT) {
            r.size.height = IPAD_PORTRAIT_HEIGHT;
        }
        else if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft && r.size.width > IPAD_LANDSCAPE_HEIGHT) {
            r.size.width = IPAD_LANDSCAPE_HEIGHT;
            r.origin.x = STATUS_BAR_HEIGHT;
        }
        else if (self.interfaceOrientation == UIInterfaceOrientationLandscapeRight && r.size.width > IPAD_LANDSCAPE_HEIGHT) {
            r.size.width = IPAD_LANDSCAPE_HEIGHT;
        }

        superview.frame = r;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM