Swift中的自定義轉(zhuǎn)場(chǎng)動(dòng)畫

在實(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出來(lái)的視圖都是添加到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出來(lái)的控制器

presentedViewController.dismissViewControllerAnimated(true, completion:nil)

}

}

```

我還在modal出來(lái)的控制器上加了一個(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)畫了

也就是說(shuō)默認(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出來(lái)的控制器的尺寸和布局子控件等,最后在轉(zhuǎn)場(chǎng)動(dòng)畫的代理中可以設(shè)置動(dòng)畫的樣式。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容