概要
前々から使いたかったのに全然思う通りに動いてくれなかったUIPopoverPresentationControllerのpopoverLayoutMarginsがiOS13で動くようになっていました!
むしろ動くようになったことでレイアウトが崩れていましたが←
やっと役割を果たしてくれるということで、機能と使用方法のおさらいを簡単にまとめていきます。
popoverLayoutMarginsとは
PopoverのUIViewControllerを設定する際などに使うUIPopoverPresentationController
の配置に関わるプロパティです。
普通にPopoverを表示するとNavigationBarに被ってしまったりして困る時がありますね。
MarginとあるようにPopoverを表示する際に画面からのマージンを設定することで
NavigationBarに被らないようにできるはずなのですが、、
iOS8以降設定しても表示に全く変化がありませんでした。。
iOS 8 popoverpresentationcontroller popoverlayoutmargin not working - Stack Overflow
これはApple側のバグとしてレポートが提出されていましたが、iOS12になっても全然修正されず(汗
てっきりもう無くなるものだと思っていましたが!!ここへ来てまさかの復活!!笑
iOS13の動作確認中にレイアウトが崩れていたので、半信半疑使ってみて復活に気づきました。
嬉しいような悲しいような?苦笑
使用方法
環境
- iOS 13.0
- Xcode 11.0
- Swift5
コード
と言ってもかなり簡単です。
設定したいマージン値のUIEdgeInsetsをSetするだけです。
Popoverを開きたい親のUIViewControllerか、PopoverであるUIViewControllerのどちらか一方に処理を書けばいいです。
今回は親側に実装してみます。
import UIKit
class SampleViewController: UIViewController
{
/// Popoverを開く
///
/// - Parameter sender: UIButton
@IBAction func openPopover(_ sender: UIButton)
{
let popoverVC = PopoverViewController()
popoverVC.preferredContentSize = CGSize(width: 230, height: 200)
popoverVC.modalPresentationStyle = .popover
popoverVC.popoverPresentationController?.sourceView = sender
popoverVC.popoverPresentationController?.sourceRect = sender.bounds
popoverVC.popoverPresentationController?.permittedArrowDirections = .left
popoverVC.popoverPresentationController?.delegate = self
// CHECK: NavigationBarとButtonに被らないようにMarginを設定
popoverVC.popoverPresentationController?.popoverLayoutMargins = UIEdgeInsets(top: 50, left: 10, bottom: 0, right: 0)
present(popoverVC, animated: true, completion: nil)
}
}
extension ViewController: UIPopoverPresentationControllerDelegate
{
// MARK: UIPopoverPresentationControllerDelegate
/// adaptivePresentationStyle(iPhoneで表示させる場合にのみ必要)
func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle
{
return .none
}
}
これでPopoverが他のパーツに被ることなく表示できますね!