[英]How to update the frameOfPresentedViewInContainerView when using custom modal presentation?
I'm using a custom UIPresentationController to present a view modally. 我正在使用自定义UIPresentationController以模态呈现视图。 After presenting the view, the first textfield in the presented view becomes the first responder and the keyboard shows up.
呈现视图后,呈现的视图中的第一个文本字段将成为第一响应者,并显示键盘。 To ensure that the view is still visible, I move it up.
为了确保视图仍然可见,我将其向上移动。 However, when I do this the
frameOfPresentedViewInContainerView
is not matching the actual frame of the view anymore. 但是,当我这样做时,
frameOfPresentedViewInContainerView
不再与视图的实际框架匹配。 Because of this, when I tap on the view it's being dismissed, because there's a tapGestureRecogziner on the backgroundView which is on top of the presentingView. 因此,当我点击视图时,该视图将被关闭,因为在presentingView顶部的backgroundView上有一个tapGestureRecogziner。 How to notify the presentingController that the frame/position of the presentedView has changed?
如何通知presentingController PresentedView的框架/位置已更改?
In the UIPresentationController: 在UIPresentationController中:
override var frameOfPresentedViewInContainerView: CGRect {
var frame = CGRect.zero
let safeAreaBottom = self.presentingViewController.view.safeAreaInsets.bottom
guard let height = presentedView?.frame.height else { return frame }
if let containerBounds = containerView?.bounds {
frame = CGRect(x: 0,
y: containerBounds.height - height - safeAreaBottom,
width: containerBounds.width,
height: height + safeAreaBottom)
}
return frame
}
override func presentationTransitionWillBegin() {
if let containerView = self.containerView, let coordinator = presentingViewController.transitionCoordinator {
containerView.addSubview(self.dimmedBackgroundView)
self.dimmedBackgroundView.backgroundColor = .black
self.dimmedBackgroundView.frame = containerView.bounds
self.dimmedBackgroundView.alpha = 0
coordinator.animate(alongsideTransition: { _ in
self.dimmedBackgroundView.alpha = 0.5
}, completion: nil)
}
}
Presenting the view modally: 模态呈现视图:
let overlayVC = CreateEventViewController()
overlayVC.transitioningDelegate = self.transitioningDelegate
overlayVC.modalPresentationStyle = .custom
self.present(overlayVC, animated: true, completion: nil)
Animation when keyboard appears (in the presented view): 出现键盘时的动画(在显示的视图中):
@objc func animateWithKeyboard(notification: NSNotification) {
let userInfo = notification.userInfo!
guard let keyboardHeight = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height,
let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double,
let curve = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt else {
return
}
// bottomContraint is the constraint that pins content to the bottom of the superview.
let moveUp = (notification.name == UIResponder.keyboardWillShowNotification)
bottomConstraint.constant = moveUp ? (keyboardHeight) : originalBottomValue
let options = UIView.AnimationOptions(rawValue: curve << 16)
UIView.animate(withDuration: duration, delay: 0,
options: options,
animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}
From the Apple documentation: 从Apple文档中:
UIKit calls this method multiple times during the course of a presentation, so your implementation should return the same frame rectangle each time.
在演示过程中,UIKit多次调用此方法,因此您的实现每次应返回相同的框架矩形。 Do not use this method to make changes to your view hierarchy or perform other one-time tasks.
不要使用此方法更改视图层次结构或执行其他一次性任务。
AFAIK, if you specify frame through this variable, it's advised not to change it throughout the course of presentation. AFAIK,如果通过此变量指定框架,建议在整个演示过程中不要更改它。 If you plan to play around with the frames, don't specify this variable and handle all the changes manually in your animator
如果您打算使用框架,请不要指定此变量并在动画师中手动处理所有更改
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.