How to present a modal atop the current view in Swift

狂风中的少年 提交于 2019-11-27 11:35:21

First, remove all explicit setting of modal presentation style in code and do the following:

  1. In the storyboard set the ModalViewController's modalPresentation style to Over Current context

  1. Check the checkboxes in the Root/Presenting ViewController - Provide Context and Define Context. They seem to be working even unchecked.

You can try this code for Swift

 let popup : PopupVC = self.storyboard?.instantiateViewControllerWithIdentifier("PopupVC") as! PopupVC
 let navigationController = UINavigationController(rootViewController: popup)
 navigationController.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
 self.presentViewController(navigationController, animated: true, completion: nil)

For swift 4 latest syntax using extension

extension UIViewController {
    func presentOnRoot(`with` viewController : UIViewController){
        let navigationController = UINavigationController(rootViewController: viewController)
        navigationController.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
        self.present(navigationController, animated: false, completion: nil)
    }
}

How to use

let popup : PopupVC = self.storyboard?.instantiateViewControllerWithIdentifier("PopupVC") as! PopupVC
self.presentOnRoot(with: popup)

The only problem I can see in your code is that you are using CurrentContext instead of OverCurrentContext.

So, replace this:

self.modalPresentationStyle = UIModalPresentationStyle.CurrentContext
self.navigationController.modalPresentationStyle = UIModalPresentationStyle.CurrentContext

for this:

self.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
self.navigationController.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext

The problem with setting the modalPresentationStyle from code was that you should have set it in the init() method of the presented view controller, not the parent view controller.

From UIKit docs: "Defines the transition style that will be used for this view controller when it is presented modally. Set this property on the view controller to be presented, not the presenter. Defaults to UIModalTransitionStyleCoverVertical."

The viewDidLoad method will only be called after you already presented the view controller.

The second problem was that you should use UIModalPresentationStyle.overCurrentContext.

The only way I able to get this to work was by doing this on the presenting view controller:

    func didTapButton() {
    self.definesPresentationContext = true
    self.modalTransitionStyle = .crossDissolve
    let yourVC = self.storyboard?.instantiateViewController(withIdentifier: "YourViewController") as! YourViewController
    let navController = UINavigationController(rootViewController: yourVC)
    navController.modalPresentationStyle = .overCurrentContext
    navController.modalTransitionStyle = .crossDissolve
    self.present(navController, animated: true, completion: nil)
}

I am updating a simple solution. First add an id to your segue which presents modal. Than in properties change it's presentation style to "Over Current Context". Than add this code in presenting view controller (The controller which is presenting modal).

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let Device = UIDevice.currentDevice()

    let iosVersion = NSString(string: Device.systemVersion).doubleValue

    let iOS8 = iosVersion >= 8
    let iOS7 = iosVersion >= 7 && iosVersion < 8
    if((segue.identifier == "chatTable")){

    if (iOS8){


          }
        else {

            self.navigationController?.modalPresentationStyle = UIModalPresentationStyle.CurrentContext


        }
    }
}

Make sure you change segue.identifier to your own id ;)

This worked for me in Swift 5.0. Set the Storyboard Id in the identity inspector as "destinationVC".

@IBAction func buttonTapped(_ sender: Any) {
    let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    let destVC = storyboard.instantiateViewController(withIdentifier: "destinationVC") as! MyViewController

    destVC.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
    destVC.modalTransitionStyle = UIModalTransitionStyle.crossDissolve

    self.present(destVC, animated: true, completion: nil)
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!