UIPopoverPresentationControllerで表示場所について試してみたこと


はじめに

従来使っていたUIPopoverControllerクラスがiOS9で廃止され、新しいクラス(UIPopoverPresentationController)に入れ替える作業をしていましたが、ドキュメントを読んでも分からなかったことがあったのでメモしておきます。

分からなかったこと

Popover表示場所を決めるプロパティ sourceView, sourceRectになにを指定すれば良いのか。
Appleドキュメントにはこう説明が書いています。

うん。。。。

コードを書いてみた

コメントに簡単な説明を書いてますが、yellowViewとredRectの関係を注目。

ViewController.swift
class ViewController: UIViewController {

    @IBOutlet weak var yellowView: UIView!

    let redRect = CGRect(x: 200, y: 100, width: 50, height: 10)

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let testView = UIView(frame: redRect)
        testView.backgroundColor = UIColor.red
        yellowView.addSubview(testView)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func openPopover(_ sender: UIButton) {

        let contentVC = PopoverContentViewController(style: .plain)

        //Popoverスタイル
        contentVC.modalPresentationStyle = .popover

        //Popoverコンテンツのサイズ
        contentVC.preferredContentSize = CGSize(width: 150, height: 100)

        //場所を決める
        contentVC.popoverPresentationController?.sourceView = yellowView
        contentVC.popoverPresentationController?.sourceRect = redRect
//        contentVC.popoverPresentationController?.sourceView = sender
//        contentVC.popoverPresentationController?.sourceRect = sender.bounds

        //方向
        contentVC.popoverPresentationController?.permittedArrowDirections = .any

        contentVC.popoverPresentationController?.delegate = self
        present(contentVC, animated: true, completion: nil)

    }
}

extension ViewController : UIPopoverPresentationControllerDelegate {

}

そして結果を見ると、

分かったこと

本当に簡単なことでした。
sourceViewはsourceRectの基準になる領域(View)になります。
そして、sourceRectはPopoverを表示する領域です。

少し考えなければいけないのは、もし、sourceViewUIScrollViewまたはUITableViewContentViewの場合、sourceRectの指定にoffsetに基づいて指定することです。

例のコードでは書いてないですが、tableViewのcellをタップした場合、offsetを反映したsourceRectを指定したところ、想定通り表示されるのを確認しました。

以上。