使用UIModalPresentationStyleCurrentContext呈现视图控制器时的布局问题 [英] Layout issues when presenting a view controller with UIModalPresentationStyleCurrentContext

查看:686
本文介绍了使用UIModalPresentationStyleCurrentContext呈现视图控制器时的布局问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了与iPad上的 UISplitViewController 和模态视图控制器有关的问题,所以我试图在一个小项目中重现这个问题,看看能不能弄清楚发生了什么。不幸的是,问题似乎仍然存在,但我无法弄清楚原因。

I ran into a problem having to do with UISplitViewController and modal view controllers on the iPad, so I tried to reproduce the issue in a small project to see if I could figure out what was going on. Unfortunately, the problem seems to still be occurring, but I can't figure out why.

我在下面包含了一个非常小的,完整的Swift程序,可以重现问题。基本上,如果您在iPad上的新Swift iOS项目中运行该代码,您将看到以下行为:

I've included a very small, complete Swift program below that reproduces the problem. Basically, if you run that code in a new Swift iOS project on the iPad, you'll see the following behavior:

该应用程序将从以下UI开始:

The app will start with the following UI:

如果我点击Present,新的模态控制器将出现在分割控制器的细节侧。如果我点击该模态控制器上的Dismiss,我将返回相同的初始界面,一切都很好。

If I tap Present, a new modal controller will present over the detail side of the split controller. If I tap Dismiss on that modal controller, I'll return to the same initial interface and all is well.

但是,如果我点击Present,然后点击Present on the出现的模态控制器(所以我在原始细节视图上有两个模态控制器),然后关闭顶部控制器, RightViewController 接管整个屏幕,消除了拆分视图控制器:

However, if I tap Present, then tap Present on the modal controller that appears (so I have two modal controllers over the original details view), and then dismiss the top one, the RightViewController takes over the entire screen, eliminating the split view controller:

整个下午我一直在反对这个问题。有什么我缺少的吗?

I've been banging my head against this all afternoon. Is there something I'm missing?

以下是示例应用程序的完整来源:

Here is the complete source for the example application:

import UIKit

class RightController: UIViewController {
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        self.title = "Right"
    }

    required init(coder aDecoder: NSCoder) {
      fatalError("init(coder:) has not been implemented")
    }

    override func loadView() {
        super.loadView()

        let label = UILabel(frame: CGRect(x: 0, y: 100, width: 100, height: 20))
        label.text = "Top Left"
        self.view.addSubview(label)

        let presButton = UIBarButtonItem(title: "Present", style: .Plain, target: self, action: Selector("present:"))

        self.navigationItem.rightBarButtonItem = presButton
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Dismiss", style: .Plain, target: self, action: Selector("dismiss:"))
    }

    func dismiss(sender: AnyObject) {
        self.dismissViewControllerAnimated(true, completion: nil)
    }

    func present(sender: AnyObject) {
        let rc = RightController()
        let nav = UINavigationController(rootViewController: rc)
        nav.modalPresentationStyle = .CurrentContext
        self.presentViewController(nav, animated: true, completion: nil)
    }
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDelegate {
    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        let splitViewController = UISplitViewController()
        splitViewController.delegate = self

        let nav1 = UINavigationController(rootViewController: UIViewController())
        nav1.title = "Left"

        let nav2 = UINavigationController(rootViewController: RightController())

        splitViewController.viewControllers = [nav1, nav2]
        self.window!.rootViewController = splitViewController

        return true
    }
}

extension AppDelegate: UISplitViewControllerDelegate {
    func splitViewController(svc: UISplitViewController, shouldHideViewController vc: UIViewController, inOrientation orientation: UIInterfaceOrientation) -> Bool {
        return false
    }
}

编辑:循环浏览设备的方向会导致分割视图控制器正确重绘,至少直到再次按下Dismiss。

EDIT: Cycling through the device's orientations causes the split view controller to redraw itself correctly, at least until Dismiss is pressed again.

EDIT :如果我在iOS 8中使用新的 .OverCurrentContext 演示文稿样式,我也可以使用它。但是,我不能放弃与iOS 7的兼容性,所以我需要一个不同的解决方案。

EDIT: I can also get this to work if I use the new .OverCurrentContext presentation style in iOS 8. However, I can't drop compatibility with iOS 7, so I need a different solution.

推荐答案

我有一个有效的解决方案虽然我会是第一个承认的,它确实感觉有点哈克。我认为你问题的很大一部分源于 .CurrentContext 的变化,经过一些测试后我发现它对iOS 7和8+的功能有所不同。因此,如果您根据iOS版本选择合适的样式,一切都会有效:

I have a solution that works although I will be the first to admit, it does feel a little hacky. I think a big part of your issue stems from a change in .CurrentContext and after some testing I found that it functions differently for iOS 7 and 8+. So everything works expectedly if you choose the proper style based on the iOS version:

var presStyle: UIModalPresentationStyle = (UIDevice.currentDevice().systemVersion as NSString).integerValue == 7 ? .CurrentContext : .OverCurrentContext
nav.modalPresentationStyle = presStyle

这篇关于使用UIModalPresentationStyleCurrentContext呈现视图控制器时的布局问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆