ios - 在交互式解雇期间动画更改 presentingViewController
<p><p>我正在开发类似于 Mail.app 的打开草稿行为的 UIPresentationController 子类。呈现 ViewController 时,它不会一直到顶部,呈现的 ViewController 会缩小,就好像它正在回落一样。</p>
<p>它的基本要点如下:</p>
<pre><code>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
}
}
</code></pre>
<p>这适用于非交互式演示或解雇。然而,在执行交互式解除时,<code>presentingViewController.view</code> 上的所有动画都以非交互方式运行。也就是说,缩放将在通常需要关闭的大约 300 毫秒内发生,而不是在 3% 关闭时保持在 3% 完成。</p>
<p>您可以在 <a href="https://github.com/bnickel/interactive-parent-transform-bug" rel="noreferrer noopener nofollow">a sample project is available on GitHub.</a> 中看到这一点和 <a href="https://www.youtube.com/watch?v=BRbH0GauCt4" rel="noreferrer noopener nofollow">a video of the issue is on YouTube</a> .</p>
<p>我尝试了以下方法,但它们都产生了相同的结果:</p>
<ul>
<li>如上所示的并行动画。</li>
<li>在 UIViewControllerAnimatedTransitioning 中制作动画。</li>
<li>使用 CABasicAnimation 手动调整容器 View 层的时间。</li>
</ul></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>问题在于 <code>presentingViewController</code> 不是演示文稿的 <code>containerView</code> 的后代。 <code>UIPercentDrivenInteractiveTransition</code> 通过将 <code>containerView.layer.speed</code> 设置为零并设置 <code>containerView.layer.timeOffset</code> 来反射(reflect)完成百分比。由于有问题的 View 不是层次结构的一部分,因此它的速度保持在 1 并且正常完成。</p>
<p>这在 <code>animateAlongsideTransition(_:,completion:)</code> 的文档中有明确说明:</p>
<blockquote>
<p>Use this method to perform animations that are not handled by the animator objects themselves. <strong>All of the animations you specify must occur inside the animation context’s container view (or one of its descendants).</strong> Use the containerView property of the context object to get the container view. <strong>To perform animations in a view that does not descend from the container view, use the <code>animateAlongsideTransitionInView:animation:completion:</code> method instead.</strong></p>
</blockquote>
<p>如文档所示,切换到 <code>animateAlongsideTransitionInView(_:,animation:,completion:)</code> 可以解决问题:</p>
<pre><code>// 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())
})
}
</code></pre>
<p>标题中对该方法的注释比文档更直接:</p>
<blockquote>
<p>// 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.</p>
</blockquote></p>
<p style="font-size: 20px;">关于ios - 在交互式解雇期间动画更改 presentingViewController,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/36775216/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/36775216/
</a>
</p>
页:
[1]