Skip to content

Commit

Permalink
Added project sources
Browse files Browse the repository at this point in the history
  • Loading branch information
askopin committed Dec 4, 2018
1 parent 8e655cd commit 9a8e2c6
Show file tree
Hide file tree
Showing 53 changed files with 1,931 additions and 894 deletions.
12 changes: 12 additions & 0 deletions CBFlashyTabBarController.podspec
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.
19 changes: 19 additions & 0 deletions CBFlashyTabBarController/CBFlashyTabBarController.h
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.
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)
}

}
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()
}

}
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
}

}
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
}

}
Loading

0 comments on commit 9a8e2c6

Please sign in to comment.