【问题标题】:Presenting viewcontroller over current context is modal and does not rotate correctly在当前上下文中呈现视图控制器是模态的并且不能正确旋转
【发布时间】:2018-07-29 10:32:56
【问题描述】:

这适用于 iOS 11.4、Swift 4 和 Xcode 9。

我试图在当前上下文上显示一个视图控制器,以便底层上下文变暗但仍然可见。我使用以下代码执行此操作:

let storyboard = UIStoryboard(name: "Main", bundle: nil)l
let vc = storyboard.instantiateViewController(withIdentifier: "LoginView") as! LoginViewController
vc.modalPresentationStyle = .overCurrentContext
vc.modalTransitionStyle   = .coverVertical

present(vc, animated: true, completion: nil)
                
let ppc = vc.popoverPresentationController
                
ppc?.sourceView = tableView
ppc?.sourceRect = tableView.bounds
ppc?.delegate = vc

LoginViewController 有一个位于其主视图中心的视图 (popview),其中包含我的可编辑控件。 这最初工作正常,但我遇到了一些问题:

  1. 呈现的视图控制器行为模式。 IE。我无法通过单击外部弹出视图来关闭它。正如我所假设的,这是因为呈现视图控制器的视图永远不会收到触摸事件,因为它们被呈现的视图捕获。
  2. 当设备旋转到横向时,只有部分屏幕被 LoginViewController 的暗色视图填充。

我尝试通过对 LoginViewController 的主视图使用通道视图来解决问题 1

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView?
{
    let view = super.hitTest(point, with: event)
    return view == self ? nil : view
}

这没有帮助。 我可以在主视图上使用 UITapGestureRecognizer 并在触摸没有弹出视图时从那里调用解除,但这对我来说似乎相当笨拙,我想知道是否有更好的方法。

我不知道如何解决问题 2。我尝试了 UIPopoverPresentationController 的委托功能,但这也不起作用,因为 当我使用 .overCurrentContext 时,vc.popoverPresentationController 始终为零。

当我将 modalPresentationStyle 设置为 .popover 时,我得到了 popoverPresentationController 的值,但我的 LoginView 将完全覆盖呈现控制器视图。

【问题讨论】:

    标签: ios swift overlay viewcontroller popover


    【解决方案1】:

    经过更多的挖掘,我最终找到了问题 2 的解决方案,以 Android 方式进行:

    presenting 视图控制器中我添加了函数:

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
    {
        if (loginViewController != nil)
        {
            present(loginViewController!, animated:false, completion: nil)
        }
    }
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
    {
        super.viewWillTransition(to: size, with: coordinator)
    
        loginViewController!.dismiss(animated: false, completion: nil)
    
    }
    

    因此,当方向发生变化时,弹出视图首先被关闭,并且在执行更改后再次显示弹出视图。由于呈现的视图控制器在此过程中没有受到伤害,即使已经在呈现的视图控制器的控件中输入的数据仍然存在。

    为了解决问题 1,我在 presented 视图控制器中添加了:

    override func viewDidLoad()
    { 
        super.viewDidLoad()
    
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
        view.addGestureRecognizer(tapGesture)
    }
    

    @objc func handleTap(sender: UITapGestureRecognizer)
    {
        let touchpoint = sender.location(in: view)
        let popviewrect = popview.frame
    
        if (!popviewrect.contains(touchpoint))
        {
            dismiss(animated: true, completion: nil)
            delegate?.onDismissed()
        }      
    }
    

    presenting 控制器实现 onDismissed 委托:

    func onDismissed()
    {
        loginViewController = nil
    }
    

    仍然想知道是否有更优雅的方法来做到这一点

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多