Collin Zhang
Collin Zhang

Reputation: 513

Popover View positions to wrong place when rotated

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?

Upvotes: 0

Views: 1002

Answers (1)

Shashank Mishra
Shashank Mishra

Reputation: 1077

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

Upvotes: 3

Related Questions