问题
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.
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:
The app will start with the following UI:
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.
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
}
}
EDIT: Cycling through the device's orientations causes the split view controller to redraw itself correctly, at least until Dismiss is pressed again.
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.
回答1:
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
来源:https://stackoverflow.com/questions/29242286/layout-issues-when-presenting-a-view-controller-with-uimodalpresentationstylecur