Presenting viewcontroller over current context is modal and does not rotate correctly

Multi tool use
Multi tool use
The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


Presenting viewcontroller over current context is modal and does not rotate correctly



This is with iOS 11.4, Swift 4 and XCode 9.



Im trying to present a viewcontroller over current context, so that the underlying context gets dimmed but still visible. I do this with following code:


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 has a view (popview) centered in it's mainview which contains my editable controls.
This works initially fine but I got a few problems:



I tried to fix problem 1 by using a passtrough view for the LoginViewController's main view with


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



This doesn't help.
I could use a UITapGestureRecognizer on the mainview and call dismiss from there if the touch is not withing popview, but that seems to be rather clumsy to me and I wonder if there is a better way.



I have no idea how to solve problem 2. I tried the delegate functions of the UIPopoverPresentationController but this doesn't work either because
vc.popoverPresentationController is always nil when I use .overCurrentContext.



When I set modalPresentationStyle to .popover I get a value for the popoverPresentationController, but than my LoginView will cover the presenting controllers view completely.




1 Answer
1



After some more digging around I found eventually a solution for problem 2 doing it the Android way:



In the presenting view controller I added to functions:


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)

}



Thus when a orientation change is incoming the popover view is first dismissed and after the change has been performed the popover is presented again. As the presented viewcontroller is unharmed during this process even data already entered in the presented viewcontroller's controls remain.



To solve problem 1 I added in the presented viewcontroller:


override func viewDidLoad()
{
super.viewDidLoad()

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
view.addGestureRecognizer(tapGesture)
}



and


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



The presenting controller implements the onDismissed delegate:


func onDismissed()
{
loginViewController = nil
}



Still wondering if there is a more elegant way to do this






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Pl4kob1t8aXV
26z 83 wZfQA8

Popular posts from this blog

Makefile test if variable is not empty

Visual Studio Code: How to configure includePath for better IntelliSense results

Will Oldham