【问题标题】:How to present a modal atop the current view in Swift如何在 Swift 中的当前视图上呈现模态
【发布时间】:2014-08-11 17:42:42
【问题描述】:

(Xcode6、iOS8、Swift、iPad)

我正在尝试创建一个经典的类似 Web 的模式视图,其中对话框的外部是“灰色的”。为此,我将模态视图的 backgroundColor 的 alpha 值设置为 0.5,如下所示:

self.view.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.5)

唯一的问题是当模态变为全屏时,呈现视图被移除。 (参考Transparent Modal View on Navigation Controller)。

(对这里的概念有点恼火。为什么要删除底层视图?根据定义,模态显示在其他内容之上。一旦底层视图被删除,它就不再是真正的模态了。它介于模态之间和一个推式过渡。哇哇哇......无论如何......)

为了防止这种情况发生,我在父控制器的 viewDidLoad 方法和 Storyboard 中将 modalPresentationStyle 设置为 CurrentContext...但没有运气。

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

当模态变为全屏时,如何防止正在显示的视图被移除?

tyvm.. 更多信息如下。

也在情节提要中,像这样(演示:当前上下文)

感谢您的帮助...文档如下:

【问题讨论】:

    标签: xcode ipad modal-dialog swift transparent


    【解决方案1】:

    首先,删除代码中模态展示样式的所有显式设置并执行以下操作:

    1. 在情节提要中将 ModalViewController 的 modalPresentation 样式设置为 Over Current context

    1. 选中根/当前视图控制器中的复选框 - Provide Context 和 Define Context。 他们似乎在不受限制地工作。

    【讨论】:

    • 这不起作用,直到我“删除了模态演示样式的所有显式设置” - 这意味着如果您有类似“vc.modalPresentationStyle = UIModalPresentationStyle.CurrentContext”的内容,您需要在故事板说明会产生影响。
    • 您的应用是通用应用还是 iPhone 专用应用?这仅适用于通用应用程序吗?
    • 非常感谢,在演示的 VC 上检查“提供上下文”和“定义上下文”使其工作。我猜故事板有时会自动将您的视图控制器定义为“提供上下文”,有时则不会,具体取决于您的视图层次结构的组织方式。
    • 美丽的答案。正是我需要的,不想在 prepareforsegue 上设置这些东西,现在我可以调用 performegue 并且视图控制器都设置好了,谢谢
    • 这个解决方案对我不起作用。也许是因为我的模态视图控制器嵌入在导航控制器中?一些帮助会很棒!
    【解决方案2】:

    你可以试试这个 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)
    

    对于swift 4最新语法使用扩展:

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

    使用方法:

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

    【讨论】:

    • 这行得通!你能告诉我它是如何使用 UINavigationController 工作的吗?为什么不使用 UINavigationController 就不能工作?
    • @Anirudha Mahale:要在没有导航控制器的情况下工作,您需要执行以下操作:让 popup : StickerCollectionVC = self.storyboard?.instantiateViewController(withIdentifier: "StickerCollectionVC") as! StickerCollectionVC popup.stickerCollectionVCDelegate = self popup.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext self.present(popup, animated: true, completion: nil)
    【解决方案3】:

    我在您的代码中看到的唯一问题是您使用的是CurrentContext 而不是OverCurrentContext。

    所以,替换这个:

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

    为此:

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

    【讨论】:

      【解决方案4】:

      这在 Swift 5.0 中对我有用。将身份检查器中的 Storyboard Id 设置为“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)
      }
      

      【讨论】:

      • 这应该是答案。可以在任何地方使用的简单逻辑
      【解决方案5】:

      从代码中设置 modalPresentationStyle 的问题是您应该在呈现的视图控制器的 init() 方法中设置它,而不是在父视图控制器中。

      来自 UIKit 文档:“定义当视图控制器以模态方式呈现时将用于此视图控制器的过渡样式。设置 要呈现的视图控制器上的此属性,而不是演示者。默认为 UIModalTransitionStyleCoverVertical。”

      viewDidLoad 方法只有在你已经展示了视图控制器之后才会被调用。

      第二个问题是你应该使用 UIModalPresentationStyle.overCurrentContext。

      【讨论】:

      • 这对我有帮助,谢谢!我试图在 viewDidLoad 中设置样式,但它发生得太晚了,但是把它扔到 init 中就可以了
      【解决方案6】:

      我能够让它工作的唯一方法是在呈现视图控制器上执行此操作:

          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)
      }
      

      【讨论】:

        【解决方案7】:

        我正在更新一个简单的解决方案。首先向你的 segue 添加一个 id 来呈现模态。比在属性中将其呈现样式更改为“Over Current Context”。比在呈现视图控制器(呈现模式的控制器)中添加此代码。

        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
        
        
                }
            }
        }
        

        确保将 segue.identifier 更改为您自己的 id ;)

        【讨论】:

        • 您正在展示 Segue 的视图?
        • 您在 iOS 7 或 iOS 8 上遇到黑屏问题?
        猜你喜欢
        • 1970-01-01
        • 2015-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多