ios - 以交互方式关闭模态视图 Controller 时出现故障

标签 ios swift modalviewcontroller interactive

我正在使用 UIViewControllerAnimatedTransitioningUIPercentDrivenInteractiveTransition 以交互方式关闭模态呈现的 View Controller 。没什么特别的。但是我注意到在交互开始时偶尔会出现一个小故障。如果使用 .curveEaseOut 选项设置动画,它会变得更加明显。我正在关注的一些在线教程 ( https://www.thorntech.com/2016/02/ios-tutorial-close-modal-dragging/ ) 也会发生同样的事情。当我第一次向下拖动时,您可以看到 gif 中的故障。有什么建议吗?

enter image description here

MyDismissAnimator

class SlideInDismissAnimator: NSObject, UIViewControllerAnimatedTransitioning {

    // ...

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

        guard let toVC = transitionContext.viewController(forKey: .to), 
        let presentedVC = transitionContext.viewController(forKey: .from) else {return}

        let presentedFrame = transitionContext.finalFrame(for: presentedVC)
        var dismissedFrame = presentedFrame
        dismissedFrame.origin.y = transitionContext.containerView.frame.size.height

        transitionContext.containerView.insertSubview(toVC.view, belowSubview: presentedVC.view)
        }
        let duration = transitionDuration(using: transitionContext)

        UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: {
            presentedVC.view.frame = dismissedFrame
        }) { _ in
            if transitionContext.transitionWasCancelled {
                toVC.view.removeFromSuperview()
            }
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        }
    }
}

我的交互器

class SwipeInteractionController: UIPercentDrivenInteractiveTransition {

    var interactionInProgress = false
    private var shouldCompleteTransition = false
    private weak var viewController: UIViewController!

    init(viewController: UIViewController) {
        self.viewController = viewController
        super.init()
        let gesture = UIPanGestureRecognizer(target: self, action: #selector(handleGesture(_:)))
        viewController.view?.addGestureRecognizer(gesture)
    }

    @objc func handleGesture(_ gestureRecognizer: UIPanGestureRecognizer) {
        let translation = gestureRecognizer.translation(in: gestureRecognizer.view!.superview!)
        var progress = (translation.y / viewController.view.bounds.height)
        progress = CGFloat(fminf(fmaxf(Float(progress), 0.0), 1.0))

        switch gestureRecognizer.state {
        case .began:
            interactionInProgress = true
            viewController.dismiss(animated: true, completion: nil)

        case .changed:
            shouldCompleteTransition = progress > 0.3
            update(progress)

        case .cancelled:
            interactionInProgress = false
            cancel()

        case .ended:
            interactionInProgress = false
            if shouldCompleteTransition {
                finish()
            } else {
                cancel()
            }
        default:
            break
        }
    }
}

最佳答案

我很确定这是 UIPercentDrivenInteractiveTransition 的错误,但我能够解决这个问题:

当调用 dismiss() 后没有尽快更新进度时会出现该错误。发生这种情况是因为平移手势识别器的 .changed 状态仅在您拖动时触发。因此,如果您缓慢拖动,在调用 .begin 和调用第一个 .changed 之间,关闭过渡将开始动画。

您可以在模拟器中看到这一点,方法是非常缓慢地逐像素拖动 View ,直到调用 .begin。只要 .changed 没有被再次调用,转换实际上会自行完成,您会看到 View 一直处于动画状态并完成转换。

但是,在 .dismiss() 之后简单地调用 update(progress) 也不起作用,我相信是因为 dismiss 动画还没有开始。 (直到下一个运行循环或其他东西)

我的“黑客”解决方案是在非常短的时间内分派(dispatch)异步,有效地设置进度并在动画开始前停止。

case .began:
    interactionInProgress = true
    viewController.dismiss(animated: true, completion: nil)
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.001) {
        self.update(progress)
    }

关于ios - 以交互方式关闭模态视图 Controller 时出现故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48666523/

相关文章:

iOS 如何从数组 Swift 中获取超过 100 个值

iphone - 编辑时 uitableview 单元格上的长按问题

iphone - 是否有可通过 iOS 访问的 API 来检测醉酒者?

ios - Swift - 导入 Objective-C 给出 "Unknown type name"

ios - 将值传递给模态 UIViewController - Swift

IOS:使用模态 ViewController 进行转换

ios - 防止关闭模态 WKInterfaceController

ios - Swift 3 应用程序中的 performSegue 无法正常工作

ios - 如何在 iOS 中有条件地为 Storyboard转场设置动画?

swift - 在 Swift 中计算中心方程