首页 文章

交互过渡不是线性的

提问于
浏览
5

我正在玩自定义和交互式视图控制器转换,使用 UIPercentDrivenInteractiveTransition . 我'm building an app that present a card (other view controller) modally. I'已经使用 UIViewControllerAnimatedTransitioning 进行了自定义转换,这使得卡视图控制器的动画效果与标准模型演示风格非常相似 .

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    {...}
    let fullScreenFrame = transitionContext.finalFrame(for: cardVC)
    let offsetFrame = cardVC.view.frame.offsetBy(dx: 0, dy: cardVC.view.frame.height)
    let finalFrame = presenting ? fullScreenFrame : offsetFrame
    cardVC.view.frame = presenting ? offsetFrame : fullScreenFrame
    containerView.addSubview(cardVC.view)

    UIView.animateKeyframes(
        withDuration: transitionDuration(using: transitionContext),
        delay: 0,
        options: UIViewKeyframeAnimationOptions.calculationModeLinear,
        animations: {
            UIView.addKeyframe(
                withRelativeStartTime: 0,
                relativeDuration: 1,
                animations: { [weak self] in
                    guard let strongSelf = self else { return }
                    backgroundView.alpha = strongSelf.presenting ? 1 : 0
            })

            UIView.addKeyframe(
                withRelativeStartTime: 0,
                relativeDuration: 1,
                animations: {
                    cardVC.view.frame = finalFrame
            })
    }, completion: { finished in
        backgroundView.removeFromSuperview()
        gradientView.alpha = 1
        transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
    })
}

然后我使用平移手势识别器以交互方式驱动解雇动画:

func handleGesture(_ gestureRecognizer: UIScreenEdgePanGestureRecognizer) {
        let translation = gestureRecognizer.translation(in: gestureRecognizer.view)
        var progress = (translation.y / (UIScreen.main.bounds.height - 70))
        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.35
            update(progress)

        case .cancelled:
            interactionInProgress = false
            cancel()

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

        default:
            print("Unsupported")
        }
    }

当我通过向下拖动它来关闭呈现的视图控制器时,它似乎不会随手势线性移动 . 似乎交互控制器正在使用一些easeInEaseOut函数 . 也许设置 UIPercentDrivenInteractiveTransitiontimingCurve 使转换线性运行 . 这是可能的,还是我弄错了?

2 回答

  • 1

    我遇到了同样的问题,能够使用 UIView.setAnimationCurveanimateKeyframes 设置自定义动画曲线,如下所示:

    UIView.animateKeyframes(withDuration: 4, delay: 0, options: [], animations: {
    
        UIView.setAnimationCurve(.linear)
    
        UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.24, animations: {
            // Animations...
        })
    
        // Other key frames...
    })
    
  • 0

    你自己已经给动画一个默认的缓和 - 缓解时间曲线,没有将时间曲线设置为你对 UIView.animateKeyframes 的调用中的任何不同 . 这甚至在互动期间也适用 .

    请注意,将动画的 options 设置为 UIViewKeyframeAnimationOptions.calculationModeLinear 不会更改时间曲线(如果您认为这是在此处完成的话) . 将线性计时曲线添加到线性计算模式关键帧动画的方法如下:

    var opts : UIViewKeyframeAnimationOptions = .calculationModeLinear
    let opt2 : UIViewAnimationOptions = .curveLinear
    opts.insert(UIViewKeyframeAnimationOptions(rawValue:opt2.rawValue))
    // and now use `opts` as your `options`
    

相关问题