8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iOS13 復活したpopoverLayoutMarginsをおさらい

Posted at

概要

前々から使いたかったのに全然思う通りに動いてくれなかったUIPopoverPresentationControllerpopoverLayoutMarginsがiOS13で動くようになっていました!
むしろ動くようになったことでレイアウトが崩れていましたが←
やっと役割を果たしてくれるということで、機能と使用方法のおさらいを簡単にまとめていきます。

popoverLayoutMarginsとは

PopoverのUIViewControllerを設定する際などに使うUIPopoverPresentationControllerの配置に関わるプロパティです。
普通にPopoverを表示するとNavigationBarに被ってしまったりして困る時がありますね。

deactive_margin.png

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のどちらか一方に処理を書けばいいです。
今回は親側に実装してみます。

SampleViewController.swift
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
    }
}

margin_active.png

これでPopoverが他のパーツに被ることなく表示できますね!

参考

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?