-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
53 changed files
with
1,931 additions
and
894 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
Pod::Spec.new do |s| | ||
s.name = 'CBFlashyTabBarController' | ||
s.version = '0.8.0' | ||
s.summary = 'One another nice animated tabbar' | ||
s.homepage = 'https://github.com/Cuberto/flashy-tabbar' | ||
s.license = 'MIT' | ||
s.author = { 'askopin@gmail.com' => 'askopin@gmail.com' } | ||
s.source = { :git => 'https://github.com/Cuberto/flashy-tabbar.git', :tag => s.version.to_s } | ||
s.ios.deployment_target = '10.0' | ||
s.swift_version = '4.2' | ||
s.source_files = 'CBFlashyTabBarController/Classes/**/*' | ||
end |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// | ||
// CBFlashyTabBarController.h | ||
// CBFlashyTabBarController | ||
// | ||
// Created by Anton Skopin on 04/12/2018. | ||
// Copyright © 2018 cuberto. All rights reserved. | ||
// | ||
|
||
#import <UIKit/UIKit.h> | ||
|
||
//! Project version number for test. | ||
FOUNDATION_EXPORT double testVersionNumber; | ||
|
||
//! Project version string for test. | ||
FOUNDATION_EXPORT const unsigned char testVersionString[]; | ||
|
||
// In this header, you should import all the public headers of your framework using statements like #import <CBFlashyTabBarController/PublicHeader.h> | ||
|
||
|
File renamed without changes.
24 changes: 24 additions & 0 deletions
24
CBFlashyTabBarController/Classes/Animation/CBTabItemAnimation.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// | ||
// CBTabItemAnimation.swift | ||
// CBFlashyTabBarController | ||
// | ||
// Created by Anton Skopin on 28/11/2018. | ||
// Copyright © 2018 cuberto. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
protocol CBTabItemAnimation { | ||
|
||
func playAnimation(forTabBarItem item: CBTabBarButton) | ||
func playAnimation(forTabBarItem item: CBTabBarButton, completion: (() -> Void)?) | ||
|
||
} | ||
|
||
extension CBTabItemAnimation { | ||
|
||
func playAnimation(forTabBarItem item: CBTabBarButton) { | ||
playAnimation(forTabBarItem: item, completion: nil) | ||
} | ||
|
||
} |
80 changes: 80 additions & 0 deletions
80
CBFlashyTabBarController/Classes/Animation/CBTabItemBasicAnimation.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// | ||
// CBTabItemBasicAnimation.swift | ||
// CBFlashyTabBarController | ||
// | ||
// Created by Anton Skopin on 28/11/2018. | ||
// Copyright © 2018 cuberto. All rights reserved. | ||
// | ||
|
||
import UIKit | ||
|
||
protocol CBTabItemBasicAnimation: CBTabItemAnimation { | ||
|
||
func imageOffsetAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation | ||
func imageMaskAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation | ||
func labelOffsetAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation | ||
func labelMaskAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation | ||
func dotScaleAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation | ||
|
||
var duration: Double { get } | ||
|
||
} | ||
|
||
extension CBTabItemBasicAnimation { | ||
|
||
func playAnimation(forTabBarItem item: CBTabBarButton, completion: (() -> Void)? = nil) { | ||
let animateImageOffset = imageOffsetAnimation(forTabBarItem: item) | ||
let animateImageMask = imageMaskAnimation(forTabBarItem: item) | ||
animateImageMask.isRemovedOnCompletion = false | ||
|
||
let animateLabelOffset = labelOffsetAnimation(forTabBarItem: item) | ||
let animateLabelMask = labelMaskAnimation(forTabBarItem: item) | ||
animateLabelMask.isRemovedOnCompletion = false | ||
|
||
let dotAnimation = dotScaleAnimation(forTabBarItem: item) | ||
|
||
let mainAnimations: [CAAnimation] = [animateImageOffset, | ||
animateImageMask, | ||
animateLabelOffset, | ||
animateLabelMask, | ||
dotAnimation] | ||
mainAnimations.forEach { (animation) in | ||
animation.duration = duration | ||
animation.isRemovedOnCompletion = false | ||
animation.fillMode = .forwards | ||
} | ||
if item.tabImage.layer.mask == nil { | ||
let imageMask = CAShapeLayer() | ||
imageMask.frame = item.tabImage.bounds | ||
item.tabImage.layer.mask = imageMask | ||
} | ||
|
||
if let animateImageMask = animateImageMask as? CAKeyframeAnimation, | ||
let imageMask = item.tabImage.layer.mask as? CAShapeLayer { | ||
imageMask.path = (animateImageMask.values as? [CGPath])?.last | ||
} | ||
|
||
if item.tabLabel.layer.mask == nil { | ||
let labelMask = CAShapeLayer() | ||
labelMask.frame = item.tabLabel.bounds | ||
item.tabLabel.layer.mask = labelMask | ||
} | ||
|
||
if let animateLabelMask = animateLabelMask as? CAKeyframeAnimation, | ||
let labelMask = item.tabLabel.layer.mask as? CAShapeLayer { | ||
labelMask.path = (animateLabelMask.values as? [CGPath])?.last | ||
} | ||
|
||
let timing = CAMediaTimingFunction(name: .easeOut) | ||
CATransaction.begin() | ||
CATransaction.setAnimationTimingFunction(timing) | ||
CATransaction.setCompletionBlock { completion?() } | ||
item.tabImage.layer.add(animateImageOffset, forKey: "offset") | ||
item.tabLabel.layer.add(animateLabelOffset, forKey: "offset") | ||
item.dotView.layer.add(dotAnimation, forKey: "scale") | ||
item.tabImage.layer.mask?.add(animateImageMask, forKey: "path") | ||
item.tabLabel.layer.mask?.add(animateLabelMask, forKey: "path") | ||
CATransaction.commit() | ||
} | ||
|
||
} |
107 changes: 107 additions & 0 deletions
107
CBFlashyTabBarController/Classes/Animation/CBTabItemDeselectAnimation.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// | ||
// CBTabItemDeselectAnimation.swift | ||
// CBFlashyTabBarController | ||
// | ||
// Created by Anton Skopin on 28/11/2018. | ||
// Copyright © 2018 cuberto. All rights reserved. | ||
// | ||
|
||
import UIKit | ||
|
||
struct CBTabItemDeselectAnimation: CBTabItemBasicAnimation { | ||
|
||
let duration: Double | ||
|
||
func imageOffsetAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation { | ||
let imageOffsetAnimation = CABasicAnimation(keyPath: "transform.translation.y") | ||
imageOffsetAnimation.fromValue = -((item.bounds.height - item.tabImage.frame.height) / 2.0 - 5.0) | ||
imageOffsetAnimation.toValue = 0.0 | ||
return imageOffsetAnimation | ||
} | ||
|
||
func imageMaskAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation { | ||
let maskBounds = item.tabImage.bounds | ||
|
||
let path1 = CGMutablePath() | ||
|
||
let path2 = CGMutablePath() | ||
path2.move(to: CGPoint(x: maskBounds.width * 0.8, y: 0)) | ||
path2.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path2.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height * 0.15)) | ||
path2.closeSubpath() | ||
|
||
let path3 = CGMutablePath() | ||
path3.move(to: .zero) | ||
path3.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path3.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height * 0.25)) | ||
path3.closeSubpath() | ||
|
||
let path4 = CGMutablePath() | ||
path4.move(to: .zero) | ||
path4.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path4.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height * 0.9)) | ||
path4.addLine(to: CGPoint(x: 0, y: maskBounds.height * 0.6)) | ||
path4.closeSubpath() | ||
|
||
let path5 = CGMutablePath() | ||
path5.move(to: .zero) | ||
path5.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path5.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height)) | ||
path5.addLine(to: CGPoint(x: 0, y: maskBounds.height)) | ||
path5.closeSubpath() | ||
|
||
let maskAnimation = CAKeyframeAnimation(keyPath: "path") | ||
maskAnimation.values = [path1, path2, path3, path4, path5] | ||
maskAnimation.keyTimes = [0.0, 0.1, 0.3, 0.7, 1.0] | ||
|
||
return maskAnimation | ||
} | ||
|
||
func labelOffsetAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation { | ||
let labelOffsetAnimation = CABasicAnimation(keyPath: "transform.translation.y") | ||
labelOffsetAnimation.fromValue = 0.0 | ||
labelOffsetAnimation.toValue = (item.bounds.height - item.tabLabel.frame.height)/2.0 - 5.0 | ||
return labelOffsetAnimation | ||
} | ||
|
||
func labelMaskAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation { | ||
let maskBounds = item.tabLabel.bounds | ||
|
||
let path1 = CGMutablePath() | ||
path1.move(to: .zero) | ||
|
||
let path2 = CGMutablePath() | ||
path2.move(to: .zero) | ||
path2.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path2.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height * 0.2)) | ||
path2.closeSubpath() | ||
|
||
let path3 = CGMutablePath() | ||
path3.move(to: .zero) | ||
path3.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path3.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height * 0.5)) | ||
path3.addLine(to: CGPoint(x: 0, y: maskBounds.height * 0.1)) | ||
path3.closeSubpath() | ||
|
||
let path4 = CGMutablePath() | ||
path4.move(to: .zero) | ||
path4.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path4.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height)) | ||
path4.addLine(to: CGPoint(x: 0, y: maskBounds.height)) | ||
path4.closeSubpath() | ||
|
||
let maskAnimation = CAKeyframeAnimation(keyPath: "path") | ||
maskAnimation.values = [path1, path2, path3, path4].reversed() | ||
maskAnimation.keyTimes = [0.0, 0.5, 0.7, 1.0] | ||
|
||
return maskAnimation | ||
} | ||
|
||
func dotScaleAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation { | ||
let dotAnimation = CAKeyframeAnimation(keyPath: "transform.scale") | ||
dotAnimation.values = [1.0, 1.0, 0.0, 0.0] | ||
dotAnimation.keyTimes = [0, 0.2, 0.7, 1.0] | ||
return dotAnimation | ||
} | ||
|
||
} |
107 changes: 107 additions & 0 deletions
107
CBFlashyTabBarController/Classes/Animation/CBTabItemSelectAnimation.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// | ||
// CBTabItemSelectAnimation.swift | ||
// CBFlashyTabBarController | ||
// | ||
// Created by Anton Skopin on 28/11/2018. | ||
// Copyright © 2018 cuberto. All rights reserved. | ||
// | ||
|
||
import UIKit | ||
|
||
struct CBTabItemSelectAnimation: CBTabItemBasicAnimation { | ||
|
||
let duration: Double | ||
|
||
func imageOffsetAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation { | ||
let imageOffsetAnimation = CABasicAnimation(keyPath: "transform.translation.y") | ||
imageOffsetAnimation.fromValue = 0.0 | ||
imageOffsetAnimation.toValue = -((item.bounds.height - item.tabImage.frame.height) / 2.0 - 5.0) | ||
return imageOffsetAnimation | ||
} | ||
|
||
func imageMaskAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation { | ||
let maskBounds = item.tabImage.bounds | ||
|
||
let path1 = CGMutablePath() | ||
path1.move(to: .zero) | ||
path1.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path1.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height)) | ||
path1.addLine(to: CGPoint(x: 0, y: maskBounds.height)) | ||
path1.closeSubpath() | ||
|
||
let path2 = CGMutablePath() | ||
path2.move(to: .zero) | ||
path2.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path2.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height * 0.9)) | ||
path2.addLine(to: CGPoint(x: 0, y: maskBounds.height * 0.6)) | ||
path2.closeSubpath() | ||
|
||
let path3 = CGMutablePath() | ||
path3.move(to: .zero) | ||
path3.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path3.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height * 0.25)) | ||
path3.closeSubpath() | ||
|
||
let path4 = CGMutablePath() | ||
path4.move(to: CGPoint(x: maskBounds.width * 0.8, y: 0)) | ||
path4.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path4.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height * 0.15)) | ||
path4.closeSubpath() | ||
|
||
let path5 = CGMutablePath() | ||
|
||
let maskAnimation = CAKeyframeAnimation(keyPath: "path") | ||
maskAnimation.values = [path1, path2, path3, path4, path5] | ||
maskAnimation.keyTimes = [0, 0.1, 0.5, 0.9, 1.0] | ||
|
||
return maskAnimation | ||
} | ||
|
||
func labelOffsetAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation { | ||
let labelOffsetAnimation = CABasicAnimation(keyPath: "transform.translation.y") | ||
labelOffsetAnimation.fromValue = (item.bounds.height - item.tabLabel.frame.height)/2.0 - 5.0 | ||
labelOffsetAnimation.toValue = 0.0 | ||
return labelOffsetAnimation | ||
} | ||
|
||
func labelMaskAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation { | ||
let maskBounds = item.tabLabel.bounds | ||
|
||
let path1 = CGMutablePath() | ||
path1.move(to: .zero) | ||
|
||
let path2 = CGMutablePath() | ||
path2.move(to: .zero) | ||
path2.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path2.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height * 0.2)) | ||
path2.closeSubpath() | ||
|
||
let path3 = CGMutablePath() | ||
path3.move(to: .zero) | ||
path3.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path3.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height * 0.5)) | ||
path3.addLine(to: CGPoint(x: 0, y: maskBounds.height * 0.1)) | ||
path3.closeSubpath() | ||
|
||
let path4 = CGMutablePath() | ||
path4.move(to: .zero) | ||
path4.addLine(to: CGPoint(x: maskBounds.width, y: 0)) | ||
path4.addLine(to: CGPoint(x: maskBounds.width, y: maskBounds.height)) | ||
path4.addLine(to: CGPoint(x: 0, y: maskBounds.height)) | ||
path4.closeSubpath() | ||
|
||
let maskAnimation = CAKeyframeAnimation(keyPath: "path") | ||
maskAnimation.values = [path1, path2, path3, path4] | ||
maskAnimation.keyTimes = [0, 0.1, 0.3, 1.0] | ||
|
||
return maskAnimation | ||
} | ||
|
||
func dotScaleAnimation(forTabBarItem item: CBTabBarButton) -> CAAnimation { | ||
let dotAnimation = CAKeyframeAnimation(keyPath: "transform.scale") | ||
dotAnimation.values = [0.0, 0.0, 1.0, 1.0] | ||
dotAnimation.keyTimes = [0, 0.2, 0.7, 1.0] | ||
return dotAnimation | ||
} | ||
|
||
} |
Oops, something went wrong.