在實(shí)際開發(fā)中經(jīng)常會(huì)出現(xiàn)的效果圖 :?
如何實(shí)現(xiàn)這種效果呢?
下面直接上代碼
```objc?
//設(shè)置轉(zhuǎn)場(chǎng)動(dòng)畫的代理
menu.transitioningDelegate=delegateOftransition
//設(shè)置轉(zhuǎn)場(chǎng)動(dòng)畫的樣式為自定義
menu.modalPresentationStyle=UIModalPresentationStyle.Custom
//執(zhí)行modal動(dòng)畫
self.presentViewController(menu, animated:true, completion:nil)
```
當(dāng)然,成為了代理還要實(shí)現(xiàn)代理方法,下面就是代理里面的代碼
```objc
extensiontransitionDelegate:UIViewControllerTransitioningDelegate{
//此方法返回一個(gè)用于負(fù)責(zé)轉(zhuǎn)場(chǎng)動(dòng)畫的對(duì)象
funcpresentationControllerForPresentedViewController(presented:UIViewController, presentingViewController presenting:UIViewController, sourceViewController source:UIViewController) ->UIPresentationController?
{
letpresentation =WLCPresentation(presentedViewController: presented, presentingViewController:presenting)
presentation.showViewFrame=menuFrame
returnpresentation
}
//返回一個(gè)控制出現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫的對(duì)象
funcanimationControllerForPresentedController(presented:UIViewController, presentingController presenting:UIViewController, sourceController source:UIViewController) ->UIViewControllerAnimatedTransitioning?
{
isPresent=true//菜單要顯示,賦值為true
returnself
}
//返回一個(gè)控制消失轉(zhuǎn)場(chǎng)動(dòng)畫的對(duì)象
funcanimationControllerForDismissedController(dismissed:UIViewController) ->UIViewControllerAnimatedTransitioning?
{
isPresent=false//菜單要消失,賦值為false
returnself
}
```
注意第一個(gè)函數(shù)返回的對(duì)象,這個(gè)對(duì)象是需要自定義的,并且繼承于UIPresentationController,這樣就可以在這個(gè)對(duì)象里面實(shí)現(xiàn)控制彈出的控制器的view的大小了,下面就是自定義的對(duì)象中的代碼了
```objc
overridefunccontainerViewWillLayoutSubviews() {
//設(shè)置彈出視圖的尺寸
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非常重要,已經(jīng)modal出來的控制器
presentedViewController.dismissViewControllerAnimated(true, completion:nil)
}
}
```
我還在modal出來的控制器上加了一個(gè)等于屏幕尺寸的按鈕,這樣只要點(diǎn)擊view以外任何一個(gè)地方就可以dismiss掉這個(gè)控制器蜒犯。
現(xiàn)在繼續(xù)回到delegateOftransition這個(gè)代理中,可以看到它還實(shí)現(xiàn)了另外兩個(gè)代理方法,返回對(duì)象均為其本身,這意味著它還要遵守UIViewControllerAnimatedTransitioning這個(gè)協(xié)議,然后實(shí)現(xiàn)協(xié)議中的方法,下面是代碼
```objc
extensiontransitionDelegate:UIViewControllerAnimatedTransitioning
{
//用于控制動(dòng)畫的時(shí)長(zhǎng)
functransitionDuration(transitionContext:UIViewControllerContextTransitioning?) ->NSTimeInterval
{
return 1.0;
}
//專門用于管理modal如何展現(xiàn)和消失的,無(wú)論是展現(xiàn)還是消失都會(huì)調(diào)用該方法
/*
注意點(diǎn):只要我們實(shí)現(xiàn)了這個(gè)方法,那么系統(tǒng)就不會(huì)再有默認(rèn)的動(dòng)畫了
也就是說默認(rèn)的modal動(dòng)畫不會(huì)再幫我們添加了,所有的動(dòng)畫操作都要我們自己實(shí)現(xiàn),包括需要展現(xiàn)的視圖也要手動(dòng)進(jìn)行添加到容器視圖(containerView)上了
*/
funcanimateTransition(transitionContext:UIViewControllerContextTransitioning)
{
ifisPresent{
presentMenu(transitionContext)
}else{
dismissMenu(transitionContext)
}
}
/**
展現(xiàn)菜單函數(shù)
*/
funcpresentMenu(transitionContext:UIViewControllerContextTransitioning){
//按鈕是選中狀態(tài),需要顯示菜單
//1.拿到需要添加的視圖
lettoView = transitionContext.viewForKey(UITransitionContextToViewKey)
//2.將需要添加的視圖添加到容器視圖(containerView)上
transitionContext.containerView()?.addSubview(toView!)
//3.設(shè)置動(dòng)畫
toView?.transform=CGAffineTransformMakeScale(1.0,0.0)
toView?.layer.anchorPoint=CGPointMake(0.5,0)
UIView.animateWithDuration(transitionDuration(transitionContext), animations: { () ->Voidin
toView?.transform=CGAffineTransformIdentity
}) { (_) ->Voidin
//注意:自定義的轉(zhuǎn)場(chǎng)動(dòng)畫,在動(dòng)畫執(zhí)行完畢后一定要告訴系統(tǒng)動(dòng)畫執(zhí)行完畢
transitionContext.completeTransition(true)
}
}
/**
*隱藏菜單函數(shù)
*/
funcdismissMenu(transitionContext:UIViewControllerContextTransitioning){
//1.拿到需要隱藏的視圖
letfromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
//2.執(zhí)行隱藏的動(dòng)畫
UIView.animateWithDuration(transitionDuration(transitionContext), animations: { () ->Voidin
fromView?.transform=CGAffineTransformMakeScale(1.0,0.00001)
}, completion: { (_) ->Voidin
//注意:自定義的轉(zhuǎn)場(chǎng)動(dòng)畫,在動(dòng)畫執(zhí)行完畢后一定要告訴系統(tǒng)動(dòng)畫執(zhí)行完畢
transitionContext.completeTransition(true)
})
}
```
總結(jié)一下,具體實(shí)現(xiàn)步驟就是設(shè)置轉(zhuǎn)場(chǎng)動(dòng)畫的代理,然后在實(shí)現(xiàn)代理方法中,需要自定義一個(gè)繼承自UIPresentationController的類,這個(gè)類里面可以控制modal出來的控制器的尺寸和布局子控件等,最后在轉(zhuǎn)場(chǎng)動(dòng)畫的代理中可以設(shè)置動(dòng)畫的樣式逻淌。