Swift中的自定义转场动画

在实际开发中经常会出现的效果图 : 

Swift中的自定义转场动画_第1张图片

如何实现这种效果呢?

下面直接上代码

```objc 

//设置转场动画的代理

menu.transitioningDelegate=delegateOftransition

//设置转场动画的样式为自定义

menu.modalPresentationStyle=UIModalPresentationStyle.Custom

//执行modal动画

self.presentViewController(menu, animated:true, completion:nil)

```

当然,成为了代理还要实现代理方法,下面就是代理里面的代码

```objc

extensiontransitionDelegate:UIViewControllerTransitioningDelegate{

//此方法返回一个用于负责转场动画的对象

funcpresentationControllerForPresentedViewController(presented:UIViewController, presentingViewController presenting:UIViewController, sourceViewController source:UIViewController) ->UIPresentationController?

{

letpresentation =WLCPresentation(presentedViewController: presented, presentingViewController:presenting)

presentation.showViewFrame=menuFrame

returnpresentation

}

//返回一个控制出现转场动画的对象

funcanimationControllerForPresentedController(presented:UIViewController, presentingController presenting:UIViewController, sourceController source:UIViewController) ->UIViewControllerAnimatedTransitioning?

{

isPresent=true//菜单要显示,赋值为true

returnself

}

//返回一个控制消失转场动画的对象

funcanimationControllerForDismissedController(dismissed:UIViewController) ->UIViewControllerAnimatedTransitioning?

{

isPresent=false//菜单要消失,赋值为false

returnself

}

```

注意第一个函数返回的对象,这个对象是需要自定义的,并且继承于UIPresentationController,这样就可以在这个对象里面实现控制弹出的控制器的view的大小了,下面就是自定义的对象中的代码了

```objc

overridefunccontainerViewWillLayoutSubviews() {

//设置弹出视图的尺寸

presentedView()?.frame.size = CGSize(width: 200, height: 200)

presentedView()?.center.x = UIScreen.mainScreen().bounds.size.width * 0.5

presentedView()?.frame.origin.y = 50

//添加返回蒙板按钮

//containerView非常重要,容器视图,所有modal出来的视图都是添加到containerView上面的

containerView?.insertSubview(bgBtn, atIndex:0)

bgBtn.addTarget(self, action:Selector("dismissClick"), forControlEvents:UIControlEvents.TouchUpInside)

}

lazyvarbgBtn :UIButton= {

letbgBtn =UIButton()

bgBtn.frame=UIScreen.mainScreen().bounds

bgBtn.backgroundColor=UIColor.clearColor()

returnbgBtn

}()

funcdismissClick(){

//presentedViewController非常重要,已经modal出来的控制器

presentedViewController.dismissViewControllerAnimated(true, completion:nil)

}

}

```

我还在modal出来的控制器上加了一个等于屏幕尺寸的按钮,这样只要点击view以外任何一个地方就可以dismiss掉这个控制器。

现在继续回到delegateOftransition这个代理中,可以看到它还实现了另外两个代理方法,返回对象均为其本身,这意味着它还要遵守UIViewControllerAnimatedTransitioning这个协议,然后实现协议中的方法,下面是代码

```objc

extensiontransitionDelegate:UIViewControllerAnimatedTransitioning

{

//用于控制动画的时长

functransitionDuration(transitionContext:UIViewControllerContextTransitioning?) ->NSTimeInterval

{

return 1.0;

}

//专门用于管理modal如何展现和消失的,无论是展现还是消失都会调用该方法

/*

注意点:只要我们实现了这个方法,那么系统就不会再有默认的动画了

也就是说默认的modal动画不会再帮我们添加了,所有的动画操作都要我们自己实现,包括需要展现的视图也要手动进行添加到容器视图(containerView)上了

*/

funcanimateTransition(transitionContext:UIViewControllerContextTransitioning)

{

ifisPresent{

presentMenu(transitionContext)

}else{

dismissMenu(transitionContext)

}

}

/**

展现菜单函数

*/

funcpresentMenu(transitionContext:UIViewControllerContextTransitioning){

//按钮是选中状态,需要显示菜单

//1.拿到需要添加的视图

lettoView = transitionContext.viewForKey(UITransitionContextToViewKey)

//2.将需要添加的视图添加到容器视图(containerView)上

transitionContext.containerView()?.addSubview(toView!)

//3.设置动画

toView?.transform=CGAffineTransformMakeScale(1.0,0.0)

toView?.layer.anchorPoint=CGPointMake(0.5,0)

UIView.animateWithDuration(transitionDuration(transitionContext), animations: { () ->Voidin

toView?.transform=CGAffineTransformIdentity

}) { (_) ->Voidin

//注意:自定义的转场动画,在动画执行完毕后一定要告诉系统动画执行完毕

transitionContext.completeTransition(true)

}

}

/**

*隐藏菜单函数

*/

funcdismissMenu(transitionContext:UIViewControllerContextTransitioning){

//1.拿到需要隐藏的视图

letfromView = transitionContext.viewForKey(UITransitionContextFromViewKey)

//2.执行隐藏的动画

UIView.animateWithDuration(transitionDuration(transitionContext), animations: { () ->Voidin

fromView?.transform=CGAffineTransformMakeScale(1.0,0.00001)

}, completion: { (_) ->Voidin

//注意:自定义的转场动画,在动画执行完毕后一定要告诉系统动画执行完毕

transitionContext.completeTransition(true)

})

}

```

总结一下,具体实现步骤就是设置转场动画的代理,然后在实现代理方法中,需要自定义一个继承自UIPresentationController的类,这个类里面可以控制modal出来的控制器的尺寸和布局子控件等,最后在转场动画的代理中可以设置动画的样式。

你可能感兴趣的:(Swift中的自定义转场动画)