在当前上下文上显示视图控制器是模态的,不能正确旋转



这适用于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. 呈现的视图控制器表现为模态。也就是说,我不能通过在popview外部点击来消除它。正如我所假设的,这是因为呈现的视图控制器视图从未接收到触摸事件,因为它们由呈现的视图捕获
  2. 当设备旋转到横向时,只有屏幕的一部分被LoginViewController的灰色视图填充

我试图通过使用带有的LoginViewController主视图的passthrough视图来解决问题1

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

这无济于事。如果触摸不在popview中,我可以在主视图上使用UIMapGestureRecognizer并从那里调用disse,但这对我来说似乎相当笨拙,我想知道是否有更好的方法。

我不知道如何解决问题2。我尝试了UIPopoverPresentationControlroller的委派功能,但这也不起作用,因为当我使用.overCurrentContext.时,vc.popoverPresentationContainer总是为零

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

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

演示视图控制器中,我添加了以下功能:

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

因此,当方向改变到来时,popover视图首先被忽略,并且在执行了改变之后,popover被再次呈现。由于所呈现的视图控制器在该过程中没有受到伤害,因此即使已经输入到所呈现视图控制器的控件中的数据也会保留下来。

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

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

呈现控制器实现onDismissed委托:

func onDismissed()
{
loginViewController = nil
}

仍然想知道是否有更优雅的方法来完成

最新更新