一 設(shè)置控制器代理 transitioningDelegate
pictureVC.transitioningDelegate = self
二 設(shè)置轉(zhuǎn)場(chǎng)模式 modalPresentationStyle
pictureVC.modalPresentationStyle = UIModalPresentationStyle.Custom
默認(rèn)的轉(zhuǎn)場(chǎng) 系統(tǒng)present之后 底層的view被移除出控制器
自定義轉(zhuǎn)場(chǎng) 底層的view依舊在 新的視圖只是遮蓋在上面
三 遵守協(xié)議 UIViewControllerTransitioningDelegate
- 實(shí)現(xiàn)代理方法
extension HomeTableViewController: UIViewControllerTransitioningDelegate {
/**
返回提供轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的對(duì)象 這個(gè)對(duì)象可以是任何一個(gè)對(duì)象 只要遵守了 UIViewControllerAnimatedTransitioning 協(xié)議
*/
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return self
}
/**
返回提供解除動(dòng)畫(huà)的對(duì)象
*/
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return self
}
}
- 此時(shí)兩個(gè)方法會(huì)報(bào)錯(cuò) 因?yàn)?return self 沒(méi)有遵守協(xié)議
UIViewControllerAnimatedTransitioning
在寫(xiě)一個(gè)類擴(kuò)展遵守協(xié)議
extension HomeTableViewController: UIViewControllerAnimatedTransitioning {
}
- 此時(shí)錯(cuò)誤會(huì)轉(zhuǎn)移到下邊的類擴(kuò)展 因?yàn)闆](méi)有實(shí)現(xiàn)協(xié)議方法 協(xié)議方法中有兩個(gè)必須一個(gè)可選
extension HomeTableViewController: UIViewControllerAnimatedTransitioning {
// 轉(zhuǎn)場(chǎng)動(dòng)畫(huà)時(shí)長(zhǎng)
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 2.0
}
/**
自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà)
- parameter transitionContext: 提供了轉(zhuǎn)場(chǎng)動(dòng)畫(huà)所需要的元素
*/
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
// 此方法必須實(shí)現(xiàn)(API 注明)
transitionContext.completeTransition(true)
}
}
此時(shí)運(yùn)行代碼 發(fā)現(xiàn)不會(huì)彈出控制器了 因?yàn)橹灰獙?shí)現(xiàn)了此方法 就需要自己寫(xiě)動(dòng)畫(huà)
func animateTransition(transitionContext: UIViewControllerContextTransitioning)
此時(shí)需要先把 上邊的 返回解除轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的方法注釋掉
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?
extension HomeTableViewController: UIViewControllerAnimatedTransitioning {
// 轉(zhuǎn)場(chǎng)動(dòng)畫(huà)時(shí)長(zhǎng)
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 2.0
}
/**
自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà) 只要實(shí)現(xiàn)了此方法 就需要自己寫(xiě)動(dòng)畫(huà)
- parameter transitionContext: 提供了轉(zhuǎn)場(chǎng)動(dòng)畫(huà)所需要的元素
- transitionContext.completeTransition(true) 動(dòng)畫(huà)結(jié)束后必須調(diào)用
- containerView() 容器視圖
- viewForKey 獲取到轉(zhuǎn)場(chǎng)的視圖 ios8.0
*/
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
// MainViewController 彈出視圖的控制器
let fromVc = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
// 要展現(xiàn)的控制器
let toVc = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!
transitionContext.containerView()?.addSubview(toView)
toView.alpha = 0.0
UIView.animateWithDuration(transitionDuration(transitionContext), animations: {
toView.alpha = 1.0
}) { (_) in
// 此方法必須實(shí)現(xiàn)(API 注明)
// 動(dòng)畫(huà)結(jié)束之后一定要執(zhí)行翅帜,如果不執(zhí)行耙厚,系統(tǒng)會(huì)一直等待,無(wú)法進(jìn)行后續(xù)交互
transitionContext.completeTransition(true)
}
}
}
此時(shí)已經(jīng)能夠?qū)崿F(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫(huà)了 接下來(lái)解決解除轉(zhuǎn)場(chǎng)定嗓, 不然關(guān)閉的時(shí)候 直接下去沒(méi)有別的動(dòng)畫(huà)
打開(kāi)剛剛注釋掉的方法
定義屬性記錄 是否已經(jīng)轉(zhuǎn)場(chǎng) 不然拿到的toView會(huì)有問(wèn)題
// 是否轉(zhuǎn)場(chǎng)
private var isPresent : Bool = true
extension HomeTableViewController: UIViewControllerTransitioningDelegate {
/**
返回提供轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的對(duì)象 這個(gè)對(duì)象可以是任何一個(gè)對(duì)象 只要遵守了 UIViewControllerAnimatedTransitioning 協(xié)議
*/
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
isPresent = true
return self
}
/**
返回提供解除動(dòng)畫(huà)的對(duì)象
*/
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
isPresent = false
return self
}
}
extension HomeTableViewController: UIViewControllerAnimatedTransitioning {
// 轉(zhuǎn)場(chǎng)動(dòng)畫(huà)時(shí)長(zhǎng)
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 2.0
}
/**
自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà) 只要實(shí)現(xiàn)了此方法 就需要自己寫(xiě)動(dòng)畫(huà)
- parameter transitionContext: 提供了轉(zhuǎn)場(chǎng)動(dòng)畫(huà)所需要的元素
- transitionContext.completeTransition(true) 動(dòng)畫(huà)結(jié)束后必須調(diào)用
- containerView() 容器視圖
- viewForKey 獲取到轉(zhuǎn)場(chǎng)的視圖 ios8.0
*/
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
// MainViewController 彈出視圖的控制器
// let fromVc = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
// 要展現(xiàn)的控制器
// let toVc = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
if isPresent {
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!
transitionContext.containerView()?.addSubview(toView)
toView.alpha = 0.0
UIView.animateWithDuration(transitionDuration(transitionContext), animations: {
toView.alpha = 1.0
}) { (_) in
// 此方法必須實(shí)現(xiàn)(API 注明)
// 動(dòng)畫(huà)結(jié)束之后一定要執(zhí)行,如果不執(zhí)行,系統(tǒng)會(huì)一直等待,無(wú)法進(jìn)行后續(xù)交互
transitionContext.completeTransition(true)
}
} else {
// 解除轉(zhuǎn)場(chǎng)的時(shí)候 fromVc 是 present出來(lái)的控制器 反了一下
let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
UIView.animateWithDuration(transitionDuration(transitionContext), animations: {
fromView.alpha = 0.0
}, completion: { (_) in
fromView.removeFromSuperview()
// 解除轉(zhuǎn)場(chǎng) 會(huì)把容器視圖和內(nèi)部視圖 銷毀
transitionContext.completeTransition(true)
})
}
}
}