简体   繁体   English

使用自定义模式演示时如何更新frameOfPresentedViewInContainerView?

[英]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.

相关问题 自定义模式演示文稿中的UIBlurEffect - UIBlurEffect in a custom modal presentation 以全屏模式演示样式使用 segue 时如何仍然显示导航栏? - how to still show navigation bar when using segue in full screen modal presentation style? 如何知道何时使用“表单”模式呈现方式呈现视图控制器 - How to know when a view controller is presented using a 'form sheet' modal presentation style 在模式演示中使用[UIViewControllerTransitionCoordinator animateAlongsideTransition:completion:]时,不调用动画块 - When using [UIViewControllerTransitionCoordinator animateAlongsideTransition:completion:] in a modal presentation, the animation block is not called 自定义缩放过渡不适用于模式演示 - Custom Zoom Transition not working for a modal presentation 具有自定义过渡的UIViewController; 模态呈现后丢失 - UIViewController with Custom Transition; Lost After Modal Presentation 使用自定义呈现控制器时保留原始状态栏外观 - Retain original status bar appearance when using custom presentation controller 在iPad上使用表单模式演示文稿时设置色彩颜色在iPad上不起作用 - Setting the tint color when using form sheet modal presentation does not work on iPad 尺寸类更改期间如何从自定义表示控制器过渡到模态? - How can I transition from a custom presentation controller to a modal during size class changes? 如何以纵向方向关闭UISplitController的模态表示 - how to dismiss a modal presentation of UISplitController in Portrait orientation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM