我正在开发一个类似于Mail.app打开草稿的UIPresentationController子类。当一个视图控制器被呈现时,它不会完全到达顶部,呈现视图控制器会像倒退一样缩小下来。
以下是基本要点:
这适用于非交互式演示或解散。但是,在执行交互式解散时,所有在 presentingViewController.view 上的动画都是非交互式运行的。也就是说,缩放将在通常需要3%的时间内完成,而不是在3%解散时保持在3%处。
您可以在GitHub 上获取可用的示例项目。以及YouTube 上有关此问题的视频。 我尝试了以下方法,但它们都产生了相同的结果:
以下是基本要点:
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 上的动画都是非交互式运行的。也就是说,缩放将在通常需要3%的时间内完成,而不是在3%解散时保持在3%处。
您可以在GitHub 上获取可用的示例项目。以及YouTube 上有关此问题的视频。 我尝试了以下方法,但它们都产生了相同的结果:
- 像上面那样平行动画。
- 在 UIViewControllerAnimatedTransitioning 中进行动画处理。
- 使用 CABasicAnimation 并手动调整容器视图层的时间。