はじめに
リファレンス(https://developer.apple.com/documentation/uikit/uiview/1622624-systemlayoutsizefittingsize)
/* The size fitting most closely to targetSize in which the receiver's subtree can be laid out while optimally satisfying the constraints.
If you want the smallest possible size, pass UILayoutFittingCompressedSize; for the largest possible size, pass UILayoutFittingExpandedSize.
Also see the comment for UILayoutPriorityFittingSizeLevel.
*/
@available(iOS 6.0, *)
open func systemLayoutSizeFitting(_ targetSize: CGSize) -> CGSize // Equivalent to sending -systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority: with UILayoutPriorityFittingSizeLevel for both priorities.
@available(iOS 8.0, *)
open func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize
使い方
targetSize
...返されるサイズのベースとなるサイズを指定します。表題の通り計算後のサイズぴったりとしたい場合は大抵UIView.layoutFittingCompressedSize
(Viewが取りうる最小サイズ)を指定します。
withHorizontalFittingPriority
...targetSizeで指定した横幅の優先度を指定します。例えば横幅に500
を指定した状態で.required
(優先度最大)を指定すると500pxになり、.fittingSizeLevel
(優先度最低)を指定すると中身に合わせて横幅が変わるイメージです。
verticalFittingPriority
...上記の縦幅バージョンです。
第2,3引数が省略された関数では、それぞれ.fittingSizeLevel
で計算されます。
以下、popover表示するViewControllerのサイズを指定する例です。
// ContentVCを生成
let contentVC = ContentViewController()
contentVC.modalPresentationStyle = .popover
// 制約通りで最小サイズ
contentVC.preferredContentSize = contentVC.view.systemLayoutSizeFitting(CGSize(width: 300, height: 0),
withHorizontalFittingPriority: .required,
verticalFittingPriority: .fittingSizeLevel)
contentVC.popoverPresentationController?.sourceView = self.view
contentVC.popoverPresentationController?.sourceRect = button.frame
contentVC.popoverPresentationController?.permittedArrowDirections = .any
// 表示
self.present(contentVC, animated: true, completion: nil)