前言:之前寫過一篇自定義TabBar動畫效果的博客OC版本,本篇換成Swift來實現(xiàn)動畫聚霜。思路大致相同,有需要可以去上篇博客中查看具體的邏輯本篇主要分享一下在Swift中核心代碼和與OC中區(qū)別珠叔。
分三步:
1:初始化:
初始化TabBar控制器
遵守UITabBarControllerDelegate代理協(xié)議蝎宇,實現(xiàn)代理方法
2:點擊動畫:
核心代碼
在代理方法tabBarController - didSelect viewController中找到對應(yīng)選中的tabBarButton并對其做核心動畫
核心代碼
/// 點擊動畫
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
tabBarButtonClick(tabBarButton: getTabBarButton())
}
private func getTabBarButton() -> UIControl {
var tabBarButtons = Array<UIView>()
for tabBarButton in tabBar.subviews {
if (tabBarButton.isKind(of:NSClassFromString("UITabBarButton")!)){
tabBarButtons.append(tabBarButton)
}
}
return tabBarButtons[selectedIndex] as! UIControl
}
private func tabBarButtonClick(tabBarButton : UIControl) {
for imageView in tabBarButton.subviews {
if (imageView.isKind(of: NSClassFromString("UITabBarSwappableImageView")!)){
let animation = CAKeyframeAnimation()
animation.keyPath = "transform.scale"
animation.duration = 0.3
animation.calculationMode = CAAnimationCalculationMode.cubicPaced
animation.values = [1.0,1.1,0.9,1.0]
imageView.layer.add(animation, forKey: nil)
}
}
}
3:滑動動畫:
在代理方法tabBarController - animationControllerForTransitionFrom代理方法中做滑動動畫。
- 這里可以創(chuàng)建一個類封裝tabBarVc的滑動動畫祷安,類似如下:
/// 滑動動畫
func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return DCSlideBarAnimation() //滑動動畫
}
在類DCSlideBarAnimation中去實現(xiàn)具體滑動動畫姥芥。
??DCSlideBarAnimation類中與OC的不同點:期初在設(shè)計OC滑動類的時候我設(shè)計一個UIRectEdge屬性來告訴類我當前選中的控制器Vc和選中前控制器Vc的一個方向偏移作為滑動動畫的dx。
??在swift中汇鞭,我取消了這個屬性凉唐,從而在類的內(nèi)部去去通過獲取當前TabVc的viewControllers的index來比較偏移方向庸追。
相比較更建議采用第二種方法,在上傳的代碼中我沒更改OC原來思路台囱,可以查看源碼進行對比淡溯。
核心代碼
// MARK: - 代理方法
extension DCSlideBarAnimation : UIViewControllerAnimatedTransitioning{
/// 設(shè)置時間間隔
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.15
}
/// 處理轉(zhuǎn)場
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let fromeVc = transitionContext.viewController(forKey: .from),
let toVc = transitionContext.viewController(forKey: .to) else { return }
guard let tabVc = UIApplication.shared.keyWindow?.rootViewController as? UITabBarController,
let fromeIndex = tabVc.viewControllers?.index(where: { $0 == fromeVc}),
let toIndex = tabVc.viewControllers?.index(where: { $0 == toVc}) else { return }
guard let formView = transitionContext.view(forKey: .from),
let toView = transitionContext.view(forKey: .to) else { return }
let fromFrame : CGRect = formView.frame
let toFrame : CGRect = toView.frame
var offSet : CGVector?
if toIndex > fromeIndex {
offSet = CGVector(dx: -1, dy: 0)
}else{
offSet = CGVector(dx: 1, dy: 0)
}
guard let animOffSet = offSet else { return }
formView.frame = fromFrame
let ofDx : CGFloat = animOffSet.dx
let ofDy : CGFloat = animOffSet.dy
toView.frame = CGRect.offsetBy(toFrame)(dx: toFrame.size.width * ofDx * -1, dy: toFrame.size.height * ofDy * -1)
transitionContext.containerView.addSubview(toView)
let transitionDuration = self.transitionDuration(using: transitionContext)
UIView.animate(withDuration: transitionDuration, animations: { //動畫
formView.frame = CGRect.offsetBy(fromFrame)(dx: fromFrame.size.width * ofDx * 1, dy: fromFrame.size.height * ofDy * 1)
toView.frame = toFrame;
}) { (_) in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
}