gpt4 book ai didi

ios - 在交互式关闭期间对 presentingViewController 进行动画更改

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:57:04 25 4
gpt4 key购买 nike

我正在研究类似于 Mail.app 的打开草稿行为的 UIPresentationController 子类。呈现 View Controller 时,它不会一直到达顶部,呈现 View Controller 会缩小,就好像它正在回退一样。

它的基本要点如下:

class CustomPresentationController : UIPresentationController {

// Create a 40pt space above the view.
override func frameOfPresentedViewInContainerView() -> CGRect {
let frame = super.frameOfPresentedViewInContainerView()
let insets = UIEdgeInsets(top: 40, left: 0, bottom: 0, right: 0)
return UIEdgeInsetsInsetRect(frame, insets)
}

// Scale down when expanded is true, otherwise identity.
private func setScale(expanded expanded: Bool) {

if expanded {
let fromMeasurement = presentingViewController.view.bounds.width
let fromScale = (fromMeasurement - 30) / fromMeasurement
presentingViewController.view.transform = CGAffineTransformMakeScale(fromScale, fromScale)
} else {
presentingViewController.view.transform = CGAffineTransformIdentity
}

}

// Scale down alongside the presentation.
override func presentationTransitionWillBegin() {
presentingViewController.transitionCoordinator()?.animateAlongsideTransition({ context in
self.setScale(expanded: true)
}, completion: { context in
self.setScale(expanded: !context.isCancelled())
})
}

// Scale up alongside the dismissal.
override func dismissalTransitionWillBegin() {
presentingViewController.transitionCoordinator()?.animateAlongsideTransition({ context in
self.setScale(expanded: false)
}, completion: { context in
self.setScale(expanded: context.isCancelled())
})
}

// Fix the scaled view's frame on orientation change.
override func containerViewWillLayoutSubviews() {
super.containerViewWillLayoutSubviews()
guard let bounds = containerView?.bounds else { return }
presentingViewController.view.bounds = bounds
}
}

这适用于非交互式演示或解雇。但是,在执行交互式关闭时,presentingViewController.view 上的所有动画都以非交互式方式运行。也就是说,缩放将在通常关闭所需的约 300 毫秒内发生,而不是在完成 3% 时保持在 3% 完成。

您可以在 a sample project is available on GitHub. 中看到这个和 a video of the issue is on YouTube .

我尝试了以下方法,但它们都产生了相同的结果:

  • 如上所示的并行动画。
  • 在 UIViewControllerAnimatedTransitioning 中制作动画。
  • 使用 CABasicAnimation 手动调整容器 View 层的时间。

最佳答案

问题是 presentingViewController 不是演示文稿的 containerView 的后代。 UIPercentDrivenInteractiveTransition 通过将 containerView.layer.speed 设置为零并设置 containerView.layer.timeOffset 来反射(reflect)完成百分比。由于相关 View 不是层次结构的一部分,因此它的速度保持在 1,并且正常完成。

animateAlongsideTransition(_:,completion:) 的文档中明确说明了这一点:

Use this method to perform animations that are not handled by the animator objects themselves. All of the animations you specify must occur inside the animation context’s container view (or one of its descendants). Use the containerView property of the context object to get the container view. To perform animations in a view that does not descend from the container view, use the animateAlongsideTransitionInView:animation:completion: method instead.

如文档所示,切换到 animateAlongsideTransitionInView(_:,animation:,completion:) 可以解决问题:

// Scale up alongside the dismissal.
override func dismissalTransitionWillBegin() {
presentingViewController.transitionCoordinator()?.animateAlongsideTransitionInView(presentingViewController.view, animation: { context in
self.setScale(expanded: false)
}, completion: { context in
self.setScale(expanded: context.isCancelled())
})
}

标题中对该方法的评论比文档更直接:

// This alternative API is needed if the view is not a descendent of the container view AND you require this animation to be driven by a UIPercentDrivenInteractiveTransition interaction controller.

关于ios - 在交互式关闭期间对 presentingViewController 进行动画更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36775216/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com