Posted at

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

More than 1 year has passed since last update.


はじめに

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


分からなかったこと

Popover表示場所を決めるプロパティ sourceView, sourceRectになにを指定すれば良いのか。

Appleドキュメントにはこう説明が書いています。

https://developer.apple.com/documentation/uikit/uipopoverpresentationcontroller

うん。。。。


コードを書いてみた

コメントに簡単な説明を書いてますが、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を指定したところ、想定通り表示されるのを確認しました。

以上。