使用演示文稿(如动作iOS 13) [英] Use presentation like actions iOS 13
问题描述
我想像标准应用程序Mail,Music和UIActivityViewController中那样实现控制器的表示.默认情况下,此控制器显示为一半,如果您滑动该控制器,它将完全打开.
I want to implement the presentation of controllers as in the standard applications Mail, Music and as in the UIActivityViewController. This controller shows on half by default and if you swipe, the controller will open completely.
我如何使用我的自定义控制器来实现此演示文稿?
How I can implement this presentation with my custom controller?
我在文档中找不到有关此演示文稿实现的参考.
I can’t find references to the implementation of such a presentation in the documentation.
屏幕截图:
推荐答案
请勿使用自定义的演示控制器,因为这样会丢失Apple提供的视觉效果和物理效果.
Do not use a custom presentation controller, because you would lose the visuals and physics provided by Apple.
正常显示,然后使用 viewDidLayoutSubviews
中的 systemLayoutSizeFitting
将框架调整为所需的最小尺寸.假设您的自定义控制器为 CustomController
,则将其替换为该子类即可.
Present normally, then use systemLayoutSizeFitting
in viewDidLayoutSubviews
to adjust the frame to the minimum required size. Assuming your custom controller is CustomController
, replace it with this subclass and you are done.
import UIKit
final class ResizedViewController: CustomController {
private let cornerRadius: CGFloat = 22
private var containerView: UIView? { view.superview }
private var presentedView: UIView? { view }
private lazy var tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(resign))
override func viewDidLoad() {
super.viewDidLoad()
tapRecognizer.cancelsTouchesInView = true
view.layer.cornerRadius = cornerRadius
view.layer.cornerCurve = .continuous
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
containerView?.addGestureRecognizer(tapRecognizer)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let recognizer = containerView?.gestureRecognizers?.first(where: { $0 == tapRecognizer }) {
containerView?.removeGestureRecognizer(recognizer)
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
view.frame = frameOfPresentedViewInContainerView
}
private var frameOfPresentedViewInContainerView: CGRect {
guard let containerView = containerView else {
return CGRect.zero
}
guard let presentedView = presentedView else {
return CGRect.zero
}
let safeBounds = containerView.bounds.inset(by: containerView.safeAreaInsets)
let newSize = CGSize(
width: safeBounds.width,
height: UIView.layoutFittingCompressedSize.height
)
let newHeight = view.safeAreaInsets.bottom +
presentedView.systemLayoutSizeFitting(
newSize,
withHorizontalFittingPriority: .required,
verticalFittingPriority: .defaultLow
).height
return CGRect(
x: 0,
y: containerView.frame.height - newHeight,
width: safeBounds.width,
height: newHeight
)
}
@objc
private func resign() {
dismiss(animated: true, completion: nil)
}
}
需要使用超级视图上的敲击识别器来消除控制器在外部的敲击.更改框架后,Apple的 cornerRadius
丢失了,所以我再次进行设置.
The tap recognizer on the superview is needed to dismiss the controller tapping outside. The cornerRadius
from Apple is lost after altering the frame so I set it again.
这篇关于使用演示文稿(如动作iOS 13)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!