根據圖示創建動畫,當點擊菜單按鈕時,需要顯示左側菜單欄
效果看起來就像一個3D動畫。現在我們來實現這種效果。
打開工程中的ContainerViewController.swift,創建3D變換函數:
func menuTransform(percent: CGFloat) -> CATransform3D {//percent表示菜單顯示的百分比進度
var identity = CATransform3DIdentity
identity.m34 = -1.0/1000//表示爲-1.0 / [camera distance],透視效果,m34 = -1 / D,D越小,透視效果越明顯,必須在有旋轉效果的前提下,纔會看到透視效果。
}
對於camera distance,有一些參考:
0.1 … 500:非常接近,很多透視變形。
750 … 2,000:視角不錯,內容清晰可見。
2000及以上:幾乎沒有透視變形。
添加代碼到menuTransform:
let remainingPercent = 1.0 - percent
let angle = remainingPercent * .pi * -0.5//計算角度
添加變換代碼:
let rotationTransform = CATransform3DRotate(identity, angle, 0.0, 1.0, 0.0)
let translationTransform = CATransform3DMakeTranslation(menuWidth * percent, 0, 0)
return CATransform3DConcat(rotationTransform, translationTransform)
爲menu添加變換,當往右拖拽時顯示菜單
menuViewController.view.layer.transform = menuTransform(percent: percent)
運行效果
默認錨點的位置在layer的中間,我們需要將錨點的x座標移動到最右邊,纔不會和內容視圖有斷層效果。在設置frame之前設置錨點:
menuViewController.view.layer.anchorPoint.x = 1.0
這樣看起來效果就很好了
因爲app的背景色是黑色的,所以我們只需要在setMenu中設置menu的alpha值即可添加陰影效果。
menuViewController.view.alpha = CGFloat(max(0.2, percent))
仔細觀察你會發現menu中的內容發生了失真:
Core Animation在你切換時不斷重繪menu控制器中的所有內容,並在所有元素移動時重新計算所有元素的透視形變,這顯然是不明智的。最好讓Core Animation知道你不會在動畫期間更改menu內容,這樣它就只需要渲染menu一次,僅僅是旋轉渲染和圖像緩存。
在手勢開始拖動的begin裏面添加代碼:
menuViewController.view.layer.shouldRasterize = true
menuViewController.view.layer.rasterizationScale = UIScreen.main.scale
shouldRasterize:指示Core Animation將圖層內容緩存爲圖像。然後設置rasterizationScale以匹配當前屏幕的scale值。
這就解決了Core Animation在動畫期間重繪的問題。
爲避免在使用應用程序時進行任何不必要的緩存,在動畫完成後,你需要關閉光柵化。
self.menuViewController.view.layer.shouldRasterize = false
現在你只是在動畫期間激活了光柵化。運行效果: