Popover View positions to wrong place when rotated

880 Views Asked by At

I may trying to center a popover and make it still centered after rotation. The research almost answered my question. However, I have noticed a very strange problem: when I initiate a popover when the device is in portrait direction, it is firstly well centered, however, if I rotate is to landscape direction, and rotate it to portrait back again, it is a little bit higher than the center position. I have made a picture by screenshots to show that

comparison between before and after

The screenshot on left is the right position, which appears when the popover is initiated firstly, the screenshot on right is the wrong position, you can see the difference clearly by the line I draw between them.

Here is the code I use to center the popover

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        if let controller = self.presentedViewController as? PopoverController {
            controller.popoverPresentationController?.sourceRect = CGRect(x: size.width / 2,
                                                                          y: size.height / 2,
                                                                          width: 0, height: 0)
            let globalPoint = controller.view.superview?.convert(controller.view.frame.origin, to: nil)
            controller.label.text = "x: \(globalPoint!.x), y: \(globalPoint!.y)"
            self.view.layoutIfNeeded()
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "popoversegue" {
            let controller = segue.destination
            controller.popoverPresentationController!.delegate = self
            controller.popoverPresentationController!.sourceRect = CGRect(x: view.center.x, y: view.center.y,
                                                                          width: 0, height: 0)
            controller.popoverPresentationController?.sourceView = self.view
            controller.preferredContentSize = CGSize(width: 500, height: 600)
            controller.popoverPresentationController!.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
        }
    }

Moreover, I have realized that the problem only occurs in portrait direction, the popover is always well centered in landscape position. What might be the problem here?

1

There are 1 best solutions below

1
On

Conform your class to "UIPopoverPresentationControllerDelegate"

Then add following code. I've tried and working fine.

func popoverPresentationController(_ popoverPresentationController: UIPopoverPresentationController, willRepositionPopoverTo rect: UnsafeMutablePointer<CGRect>, in view: AutoreleasingUnsafeMutablePointer<UIView>) {
        let viewFrame = popoverPresentationController.presentingViewController.view.frame
        let deltaX = viewFrame.height - rect.pointee.midX
        rect.pointee = CGRect(x: viewFrame.width - deltaX, y: rect.pointee.maxY, width: 0, height: 0)
    }