1.当我们在点击进行页面跳转的时候,可能觉得系统的动画和跳转的页面太过单调。这时候就需要我们自定义转场动画了。
1.1定义一个想要跳转的控制器
let presentedVC = UIViewController()
1.2为获得的控制器添加代理,并设置类扩展遵循协议
presentedVC.transitioningDelegate = self
1.3设置转场动画的样式
presentedVC.modalPresentationStyle = UIModalPresentationStyle.custom
1.4进行页面跳转
self.present(presentedVC, animated: true, completion: nil)
2.既然遵循了transitioningDelegate就要实现代理方法
extension HomeTableViewController : UIViewControllerTransitioningDelegate
{ 2.1返回控制器跳转的UIPresentationController对象
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController?
{
return HYXPresentationController(presentedViewController: presented, presenting: presenting)
}
2.2返回控制控制器弹出动画的执行者,也就是遵守UIViewControllerAnimatedTransitioning这个协议
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
return self
}
2.3返回控制控制器消失动画的执行者,也就是遵守UIViewControllerAnimatedTransitioning这个协议
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
return self
}
}
3.自定义UIPresentationController
class HYXPresentationController: UIPresentationController {
3.1自定义UIPresentationController需要重写父类的init方法
override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
}
3.2在containerView即将布局子视图的时候,更改即将推出的视图的属性
override func containerViewWillLayoutSubviews()
{
presentedView?.frame = CGRect(x: 100, y: 45, width: 200, height: 200)
}
}
4.实现UIViewControllerAnimatedTransitioning协议里面的方法
extension HomeTableViewController : UIViewControllerAnimatedTransitioning
{
4.1设置自定义动画执行时间
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval
{
return 1.0
}
4.2设置自定义动画
func animateTransition(using transitionContext: UIViewControllerContextTransitioning)
{
4.2.1通过transitionContext取出相应的即将弹出来的控制器的view
guard let viewT = transitionContext.view(forKey: UITransitionContextViewKey.to) else {
return
}
4.2.2将viwe添加在containerView里面
transitionContext.containerView.addSubview(viewT)
4.2.3设置view的执行动画
viewT.transform = CGAffineTransform.init(scaleX: 1.0, y: 0.0)
viewT.layer.anchorPoint = CGPoint(x: 0.5, y: 0.0)
UIView.animate(withDuration: 1.0, animations: {
viewT.transform = CGAffineTransform.identity
}) { (_) in
4.2.4动画结束后通知transitionContext动画完成
transitionContext.completeTransition(true)
}
}
}
以上就完成了简单的自定义转场动画
需要注意的几个点:
1.transitioningDelegate这个协议的代理方法
1).执行进入动画的控制器,并遵循UIViewControllerAnimatedTransitioning协议
optional public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning?
2).执行退出动画的控制器,并遵循UIViewControllerAnimatedTransitioning协议
optional public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?
3).获取到推入推出的两个控制器
optional public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController?
2.UIViewControllerAnimatedTransitioning这个协议的代理方法以及属性
1).设置动画的持续时间
public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval
2).进行跳转动画的设置,其中transitionContext这个很重要
public func animateTransition(using transitionContext: UIViewControllerContextTransitioning)
3.transitionContext其实就是UIViewControllerContextTransitioning协议
1).存放即将展现的控制器视图的容器
public var containerView: UIView { get }
2).可以返回指定的当前控制器或者即将进入的控制器
public func viewController(forKey key: UITransitionContextViewControllerKey) -> UIViewController?
3).可以返回指定的当前控制器或者即将进入的控制器的view
public func view(forKey key: UITransitionContextViewKey) -> UIView?