Compare commits
142 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 52174249fa | |||
| 2ea00f8238 | |||
| 50d0c1feaa | |||
| 445857fd92 | |||
| 76d074df03 | |||
| 3665d14c7a | |||
| 1bce9a939c | |||
| e546c49294 | |||
| 205354aa41 | |||
| 9687519cee | |||
| 0c07d6d8ed | |||
| 800567befc | |||
| e909d06015 | |||
| f5c9a9e444 | |||
| dd12ebf6a1 | |||
| 1799b007d7 | |||
| 85683d5870 | |||
| eccd00bc32 | |||
| 749c4a2be2 | |||
| ab650eda04 | |||
| 22f66aef17 | |||
| 2f54635f3a | |||
| 3fc716a0a6 | |||
| ba3c230eae | |||
| d7d08b2d77 | |||
| 8a0a3db9b4 | |||
| 607c2fa353 | |||
| f6723b656b | |||
| 9ddd20ee80 | |||
| d5405cf575 | |||
| 07337c67fd | |||
| c19146ef3a | |||
| 66eefb049b | |||
| 8a21f0e246 | |||
| d38f4cd350 | |||
| dacd232c4e | |||
| 25b5cd3c6f | |||
| 115a7d6eb6 | |||
| 80a5fc475f | |||
| 8234acfd58 | |||
| cf7146ed65 | |||
| 745131cd14 | |||
| 3fd4b16001 | |||
| f85db3226c | |||
| 1624f6b0c1 | |||
| 7104a8b763 | |||
| a64154cac0 | |||
| a410d7de58 | |||
| 05a3517d3c | |||
| e68a67ce46 | |||
| 6d9c386d29 | |||
| 6d44e6bfd4 | |||
| 13ce698771 | |||
| a07ebd9b3d | |||
| 50456d20f8 | |||
| 3801cd7e42 | |||
| 3dd5a62367 | |||
| ccb77d17b6 | |||
| 17e56426f4 | |||
| 685eb6ad2a | |||
| a0bb6313a3 | |||
| fd24e7c5af | |||
| 91f325c98d | |||
| c7f408943c | |||
| e5a90fdae3 | |||
| 79f4e41b7f | |||
| 976aef7b8e | |||
| 44b4b8b977 | |||
| aa02604c5f | |||
| e6bac4578e | |||
| d88a779dbc | |||
| 85a4087618 | |||
| 0c1e364439 | |||
| c987edae30 | |||
| 598ecf2788 | |||
| 519b05cfb9 | |||
| 9ea6693e58 | |||
| af57f66326 | |||
| 865dd9f07d | |||
| 0ef38b84a9 | |||
| e89ed595c5 | |||
| 73ccf08668 | |||
| 6f4ed9c0da | |||
| af732e1be9 | |||
| 53b1ab2ea7 | |||
| 5349e333b7 | |||
| c91ca6aac3 | |||
| b8ace96af5 | |||
| 8c79c11796 | |||
| 5421db8688 | |||
| 1173b4f4c1 | |||
| 0c2a124d4f | |||
| f182937e58 | |||
| 3ba7d92988 | |||
| 51436dbc01 | |||
| 2509b652b3 | |||
| d3ab502ce1 | |||
| 227bc65b48 | |||
| c8b2481fc8 | |||
| c9851ab91c | |||
| 47dbef6491 | |||
| 059c20c8d8 | |||
| 9323010bb5 | |||
| df6c959744 | |||
| a2400299c8 | |||
| 0f6e9b577c | |||
| 1f8260cec5 | |||
| c03229ceb8 | |||
| fbe2592a16 | |||
| bdfecd24a6 | |||
| 65dae9f9cf | |||
| bddfcb569a | |||
| af85d5d2ee | |||
| 9e224a29f6 | |||
| 827fb6ebf2 | |||
| a67358d8ea | |||
| bc1d66606a | |||
| 2ed27276f1 | |||
| d59ac31d62 | |||
| 439948e60f | |||
| 45da97d5f2 | |||
| 87a1580bf7 | |||
| b999173a6d | |||
| 36899687d2 | |||
| 1f1ee2ddc8 | |||
| bdaaa7e2aa | |||
| f6a68872a9 | |||
| ce75bc4c5d | |||
| 0fd8338e32 | |||
| 953158a4a4 | |||
| cfafeec5a0 | |||
| f20b1df38a | |||
| 17d3376876 | |||
| 6c00c162cf | |||
| cb1d273a9d | |||
| a1badfd79b | |||
| 67adbdbf17 | |||
| f022291904 | |||
| cc47bce6d8 | |||
| fc65f3c673 | |||
| 28a40e19f3 | |||
| ceaf333e21 |
@@ -32,3 +32,5 @@ DerivedData
|
||||
|
||||
Carthage/Build
|
||||
Status API Training Shop Blog About Pricing
|
||||
|
||||
.DS_Store
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
4.2
|
||||
@@ -1,6 +1,11 @@
|
||||
osx_image: xcode8
|
||||
osx_image: xcode10.2
|
||||
language: objective-c
|
||||
xcode_sdk: iphonesimulator12.1
|
||||
|
||||
xcode_project: RAMAnimatedTabBarDemo/RAMAnimatedTabBarDemo.xcodeproj
|
||||
xcode_scheme: AnimatedTabBar
|
||||
xcode_sdk: iphonesimulator
|
||||
xcode_scheme: RAMAnimatedTabBarController
|
||||
|
||||
# whitelist
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
// swift-tools-version:5.1
|
||||
//
|
||||
// Package.swift
|
||||
//
|
||||
// Copyright (c) Ramotion Inc. (https://www.ramotion.com/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
import PackageDescription
|
||||
|
||||
|
||||
let package = Package(
|
||||
name: "RAMAnimatedTabBarController",
|
||||
platforms: [
|
||||
.iOS(.v9)
|
||||
],
|
||||
products: [
|
||||
.library(name: "RAMAnimatedTabBarController",
|
||||
targets: ["RAMAnimatedTabBarController"]),
|
||||
],
|
||||
targets: [
|
||||
.target(name: "RAMAnimatedTabBarController",
|
||||
path: "RAMAnimatedTabBarController")
|
||||
],
|
||||
swiftLanguageVersions: [.v5]
|
||||
)
|
||||
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'RAMAnimatedTabBarController'
|
||||
s.version = '2.2.2'
|
||||
s.version = '5.2.0'
|
||||
s.license = 'MIT'
|
||||
s.summary = 'RAMAnimatedTabBarController is a Swift module for adding animation to tabbar items.'
|
||||
s.homepage = 'https://github.com/Ramotion/animated-tab-bar'
|
||||
|
||||
@@ -22,70 +22,69 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
/// The RAMBounceAnimation class provides bounce animation.
|
||||
open class RAMBounceAnimation : RAMItemAnimation {
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is selected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
override open func playAnimation(_ icon : UIImageView, textLabel : UILabel) {
|
||||
playBounceAnimation(icon)
|
||||
textLabel.textColor = textSelectedColor
|
||||
}
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is unselected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
- parameter defaultTextColor: default UITabBarItem text color
|
||||
- parameter defaultIconColor: default UITabBarItem icon color
|
||||
*/
|
||||
override open func deselectAnimation(_ icon : UIImageView, textLabel : UILabel, defaultTextColor : UIColor, defaultIconColor: UIColor) {
|
||||
textLabel.textColor = defaultTextColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderMode = defaultIconColor.cgColor.alpha == 0 ? UIImageRenderingMode.alwaysOriginal :
|
||||
UIImageRenderingMode.alwaysTemplate
|
||||
let renderImage = iconImage.withRenderingMode(renderMode)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = defaultIconColor
|
||||
open class RAMBounceAnimation: RAMItemAnimation {
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is selected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open override func playAnimation(_ icon: UIImageView, textLabel: UILabel) {
|
||||
playBounceAnimation(icon)
|
||||
textLabel.textColor = textSelectedColor
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Method call when TabBarController did load
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
override open func selectedState(_ icon : UIImageView, textLabel : UILabel) {
|
||||
textLabel.textColor = textSelectedColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = iconSelectedColor
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is unselected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
- parameter defaultTextColor: default UITabBarItem text color
|
||||
- parameter defaultIconColor: default UITabBarItem icon color
|
||||
*/
|
||||
open override func deselectAnimation(_ icon: UIImageView, textLabel: UILabel, defaultTextColor: UIColor, defaultIconColor: UIColor) {
|
||||
textLabel.textColor = defaultTextColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderMode = defaultIconColor.cgColor.alpha == 0 ? UIImage.RenderingMode.alwaysOriginal :
|
||||
UIImage.RenderingMode.alwaysTemplate
|
||||
let renderImage = iconImage.withRenderingMode(renderMode)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = defaultIconColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func playBounceAnimation(_ icon : UIImageView) {
|
||||
|
||||
let bounceAnimation = CAKeyframeAnimation(keyPath: Constants.AnimationKeys.Scale)
|
||||
bounceAnimation.values = [1.0 ,1.4, 0.9, 1.15, 0.95, 1.02, 1.0]
|
||||
bounceAnimation.duration = TimeInterval(duration)
|
||||
bounceAnimation.calculationMode = kCAAnimationCubic
|
||||
|
||||
icon.layer.add(bounceAnimation, forKey: nil)
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = iconSelectedColor
|
||||
|
||||
/**
|
||||
Method call when TabBarController did load
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open override func selectedState(_ icon: UIImageView, textLabel: UILabel) {
|
||||
textLabel.textColor = textSelectedColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = iconSelectedColor
|
||||
}
|
||||
}
|
||||
|
||||
func playBounceAnimation(_ icon: UIImageView) {
|
||||
|
||||
let bounceAnimation = CAKeyframeAnimation(keyPath: Constants.AnimationKeys.scale)
|
||||
bounceAnimation.values = [1.0, 1.4, 0.9, 1.15, 0.95, 1.02, 1.0]
|
||||
bounceAnimation.duration = TimeInterval(duration)
|
||||
bounceAnimation.calculationMode = CAAnimationCalculationMode.cubic
|
||||
|
||||
icon.layer.add(bounceAnimation, forKey: nil)
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = iconSelectedColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,113 +20,113 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
import UIKit
|
||||
import QuartzCore
|
||||
import UIKit
|
||||
|
||||
/// The RAMFrameItemAnimation class provides keyframe animation.
|
||||
open class RAMFrameItemAnimation: RAMItemAnimation {
|
||||
|
||||
@nonobjc fileprivate var animationImages : Array<CGImage> = Array()
|
||||
|
||||
var selectedImage : UIImage!
|
||||
|
||||
/// A Boolean value indicated plaing revers animation when UITabBarItem unselected, if false image change immediately, defalut value true
|
||||
@IBInspectable open var isDeselectAnimation: Bool = true
|
||||
|
||||
/// path to array of image names from plist file
|
||||
@IBInspectable open var imagesPath: String!
|
||||
|
||||
override open func awakeFromNib() {
|
||||
|
||||
guard let path = Bundle.main.path(forResource: imagesPath, ofType:"plist") else {
|
||||
fatalError("don't found plist")
|
||||
|
||||
@nonobjc fileprivate var animationImages: Array<CGImage> = Array()
|
||||
|
||||
var selectedImage: UIImage!
|
||||
|
||||
/// A Boolean value indicated plaing revers animation when UITabBarItem unselected, if false image change immediately, defalut value true
|
||||
@IBInspectable open var isDeselectAnimation: Bool = true
|
||||
|
||||
/// path to array of image names from plist file
|
||||
@IBInspectable open var imagesPath: String!
|
||||
|
||||
open override func awakeFromNib() {
|
||||
|
||||
guard let path = Bundle.main.path(forResource: imagesPath, ofType: "plist") else {
|
||||
fatalError("don't found plist")
|
||||
}
|
||||
|
||||
guard case let animationImagesName as [String] = NSArray(contentsOfFile: path) else {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
createImagesArray(animationImagesName)
|
||||
|
||||
// selected image
|
||||
let selectedImageName = animationImagesName[animationImagesName.endIndex - 1]
|
||||
selectedImage = UIImage(named: selectedImageName)
|
||||
}
|
||||
|
||||
guard case let animationImagesName as [String] = NSArray(contentsOfFile: path) else {
|
||||
fatalError()
|
||||
|
||||
func createImagesArray(_ imageNames: Array<String>) {
|
||||
for name: String in imageNames {
|
||||
if let image = UIImage(named: name)?.cgImage {
|
||||
animationImages.append(image)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createImagesArray(animationImagesName)
|
||||
|
||||
// selected image
|
||||
let selectedImageName = animationImagesName[animationImagesName.endIndex - 1]
|
||||
selectedImage = UIImage(named: selectedImageName)
|
||||
}
|
||||
|
||||
func createImagesArray(_ imageNames : Array<String>) {
|
||||
for name : String in imageNames {
|
||||
if let image = UIImage(named: name)?.cgImage {
|
||||
animationImages.append(image)
|
||||
}
|
||||
|
||||
// MARK: public
|
||||
|
||||
/**
|
||||
Set images for keyframe animation
|
||||
|
||||
- parameter images: images for keyframe animation
|
||||
*/
|
||||
open func setAnimationImages(_ images: Array<UIImage>) {
|
||||
var animationImages = Array<CGImage>()
|
||||
for image in images {
|
||||
if let cgImage = image.cgImage {
|
||||
animationImages.append(cgImage)
|
||||
}
|
||||
}
|
||||
self.animationImages = animationImages
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: public
|
||||
|
||||
/**
|
||||
Set images for keyframe animation
|
||||
|
||||
- parameter images: images for keyframe animation
|
||||
*/
|
||||
open func setAnimationImages(_ images: Array<UIImage>) {
|
||||
var animationImages = Array<CGImage>()
|
||||
for image in images {
|
||||
if let cgImage = image.cgImage {
|
||||
animationImages.append(cgImage)
|
||||
}
|
||||
|
||||
// MARK: RAMItemAnimationProtocol
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is selected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open override func playAnimation(_ icon: UIImageView, textLabel: UILabel) {
|
||||
|
||||
playFrameAnimation(icon, images: animationImages)
|
||||
textLabel.textColor = textSelectedColor
|
||||
}
|
||||
self.animationImages = animationImages
|
||||
}
|
||||
|
||||
// MARK: RAMItemAnimationProtocol
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is selected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
override open func playAnimation(_ icon : UIImageView, textLabel : UILabel) {
|
||||
|
||||
playFrameAnimation(icon, images:animationImages)
|
||||
textLabel.textColor = textSelectedColor
|
||||
}
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is unselected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
- parameter defaultTextColor: default UITabBarItem text color
|
||||
- parameter defaultIconColor: default UITabBarItem icon color
|
||||
*/
|
||||
override open func deselectAnimation(_ icon : UIImageView, textLabel : UILabel, defaultTextColor : UIColor, defaultIconColor : UIColor) {
|
||||
if isDeselectAnimation {
|
||||
playFrameAnimation(icon, images:animationImages.reversed())
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is unselected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
- parameter defaultTextColor: default UITabBarItem text color
|
||||
- parameter defaultIconColor: default UITabBarItem icon color
|
||||
*/
|
||||
open override func deselectAnimation(_ icon: UIImageView, textLabel: UILabel, defaultTextColor: UIColor, defaultIconColor _: UIColor) {
|
||||
if isDeselectAnimation {
|
||||
playFrameAnimation(icon, images: animationImages.reversed())
|
||||
}
|
||||
|
||||
textLabel.textColor = defaultTextColor
|
||||
}
|
||||
|
||||
/**
|
||||
Method call when TabBarController did load
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open override func selectedState(_ icon: UIImageView, textLabel: UILabel) {
|
||||
icon.image = selectedImage
|
||||
textLabel.textColor = textSelectedColor
|
||||
}
|
||||
|
||||
@nonobjc func playFrameAnimation(_ icon: UIImageView, images: Array<CGImage>) {
|
||||
let frameAnimation = CAKeyframeAnimation(keyPath: Constants.AnimationKeys.keyFrame)
|
||||
frameAnimation.calculationMode = CAAnimationCalculationMode.discrete
|
||||
frameAnimation.duration = TimeInterval(duration)
|
||||
frameAnimation.values = images
|
||||
frameAnimation.repeatCount = 1
|
||||
frameAnimation.isRemovedOnCompletion = false
|
||||
frameAnimation.fillMode = CAMediaTimingFillMode.forwards
|
||||
icon.layer.add(frameAnimation, forKey: nil)
|
||||
}
|
||||
|
||||
textLabel.textColor = defaultTextColor
|
||||
}
|
||||
|
||||
/**
|
||||
Method call when TabBarController did load
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
override open func selectedState(_ icon : UIImageView, textLabel : UILabel) {
|
||||
icon.image = selectedImage
|
||||
textLabel.textColor = textSelectedColor
|
||||
}
|
||||
|
||||
@nonobjc func playFrameAnimation(_ icon : UIImageView, images : Array<CGImage>) {
|
||||
let frameAnimation = CAKeyframeAnimation(keyPath: Constants.AnimationKeys.KeyFrame)
|
||||
frameAnimation.calculationMode = kCAAnimationDiscrete
|
||||
frameAnimation.duration = TimeInterval(duration)
|
||||
frameAnimation.values = images
|
||||
frameAnimation.repeatCount = 1
|
||||
frameAnimation.isRemovedOnCompletion = false
|
||||
frameAnimation.fillMode = kCAFillModeForwards
|
||||
icon.layer.add(frameAnimation, forKey: nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,111 +24,112 @@
|
||||
import UIKit
|
||||
|
||||
/// The RAMFumeAnimation class provides bounce animation.
|
||||
open class RAMFumeAnimation : RAMItemAnimation {
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is selected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
override open func playAnimation(_ icon : UIImageView, textLabel : UILabel) {
|
||||
playMoveIconAnimation(icon, values:[icon.center.y as AnyObject, (icon.center.y + 4.0) as AnyObject])
|
||||
playLabelAnimation(textLabel)
|
||||
textLabel.textColor = textSelectedColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = textSelectedColor
|
||||
open class RAMFumeAnimation: RAMItemAnimation {
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is selected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open override func playAnimation(_ icon: UIImageView, textLabel: UILabel) {
|
||||
playMoveIconAnimation(icon, values: [icon.center.y as AnyObject, (icon.center.y + 4.0) as AnyObject])
|
||||
playLabelAnimation(textLabel)
|
||||
textLabel.textColor = textSelectedColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = iconSelectedColor
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is unselected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
- parameter defaultTextColor: default UITabBarItem text color
|
||||
- parameter defaultIconColor: default UITabBarItem icon color
|
||||
*/
|
||||
override open func deselectAnimation(_ icon : UIImageView, textLabel : UILabel, defaultTextColor : UIColor, defaultIconColor : UIColor) {
|
||||
|
||||
playMoveIconAnimation(icon, values:[(icon.center.y + 4.0) as AnyObject, icon.center.y as AnyObject])
|
||||
playDeselectLabelAnimation(textLabel)
|
||||
textLabel.textColor = defaultTextColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderMode = defaultIconColor.cgColor.alpha == 0 ? UIImageRenderingMode.alwaysOriginal :
|
||||
UIImageRenderingMode.alwaysTemplate
|
||||
let renderImage = iconImage.withRenderingMode(renderMode)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = defaultIconColor
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is unselected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
- parameter defaultTextColor: default UITabBarItem text color
|
||||
- parameter defaultIconColor: default UITabBarItem icon color
|
||||
*/
|
||||
open override func deselectAnimation(_ icon: UIImageView, textLabel: UILabel, defaultTextColor: UIColor, defaultIconColor: UIColor) {
|
||||
|
||||
playMoveIconAnimation(icon, values: [(icon.center.y + 4.0) as AnyObject, icon.center.y as AnyObject])
|
||||
playDeselectLabelAnimation(textLabel)
|
||||
textLabel.textColor = defaultTextColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderMode = defaultIconColor.cgColor.alpha == 0 ? UIImage.RenderingMode.alwaysOriginal :
|
||||
UIImage.RenderingMode.alwaysTemplate
|
||||
let renderImage = iconImage.withRenderingMode(renderMode)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = defaultIconColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Method call when TabBarController did load
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
override open func selectedState(_ icon : UIImageView, textLabel : UILabel) {
|
||||
|
||||
playMoveIconAnimation(icon, values:[(icon.center.y + 12.0) as AnyObject])
|
||||
textLabel.alpha = 0
|
||||
textLabel.textColor = textSelectedColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = textSelectedColor
|
||||
|
||||
/**
|
||||
Method call when TabBarController did load
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open override func selectedState(_ icon: UIImageView, textLabel: UILabel) {
|
||||
|
||||
playMoveIconAnimation(icon, values: [(icon.center.y + 12.0) as AnyObject])
|
||||
textLabel.alpha = 0
|
||||
textLabel.textColor = textSelectedColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = iconSelectedColor
|
||||
}
|
||||
}
|
||||
|
||||
func playMoveIconAnimation(_ icon: UIImageView, values: [AnyObject]) {
|
||||
|
||||
let yPositionAnimation = createAnimation(Constants.AnimationKeys.positionY, values: values, duration: duration / 2)
|
||||
|
||||
icon.layer.add(yPositionAnimation, forKey: nil)
|
||||
}
|
||||
|
||||
// MARK: select animation
|
||||
|
||||
func playLabelAnimation(_ textLabel: UILabel) {
|
||||
|
||||
let yPositionAnimation = createAnimation(Constants.AnimationKeys.positionY, values: [textLabel.center.y as AnyObject, (textLabel.center.y - 60.0) as AnyObject], duration: duration)
|
||||
yPositionAnimation.fillMode = CAMediaTimingFillMode.removed
|
||||
yPositionAnimation.isRemovedOnCompletion = true
|
||||
textLabel.layer.add(yPositionAnimation, forKey: nil)
|
||||
|
||||
let scaleAnimation = createAnimation(Constants.AnimationKeys.scale, values: [1.0 as AnyObject, 2.0 as AnyObject], duration: duration)
|
||||
scaleAnimation.fillMode = CAMediaTimingFillMode.removed
|
||||
scaleAnimation.isRemovedOnCompletion = true
|
||||
textLabel.layer.add(scaleAnimation, forKey: nil)
|
||||
|
||||
let opacityAnimation = createAnimation(Constants.AnimationKeys.opacity, values: [1.0 as AnyObject, 0.0 as AnyObject], duration: duration)
|
||||
textLabel.layer.add(opacityAnimation, forKey: nil)
|
||||
}
|
||||
|
||||
func createAnimation(_ keyPath: String, values: [AnyObject], duration: CGFloat) -> CAKeyframeAnimation {
|
||||
|
||||
let animation = CAKeyframeAnimation(keyPath: keyPath)
|
||||
animation.values = values
|
||||
animation.duration = TimeInterval(duration)
|
||||
animation.calculationMode = CAAnimationCalculationMode.cubic
|
||||
animation.fillMode = CAMediaTimingFillMode.forwards
|
||||
animation.isRemovedOnCompletion = false
|
||||
return animation
|
||||
}
|
||||
|
||||
// MARK: deselect animation
|
||||
|
||||
func playDeselectLabelAnimation(_ textLabel: UILabel) {
|
||||
|
||||
let yPositionAnimation = createAnimation(Constants.AnimationKeys.positionY, values: [(textLabel.center.y + 15) as AnyObject, textLabel.center.y as AnyObject], duration: duration)
|
||||
textLabel.layer.add(yPositionAnimation, forKey: nil)
|
||||
|
||||
let opacityAnimation = createAnimation(Constants.AnimationKeys.opacity, values: [0 as AnyObject, 1 as AnyObject], duration: duration)
|
||||
textLabel.layer.add(opacityAnimation, forKey: nil)
|
||||
}
|
||||
}
|
||||
|
||||
func playMoveIconAnimation(_ icon : UIImageView, values: [AnyObject]) {
|
||||
|
||||
let yPositionAnimation = createAnimation(Constants.AnimationKeys.PositionY, values:values, duration:duration / 2)
|
||||
|
||||
icon.layer.add(yPositionAnimation, forKey: nil)
|
||||
}
|
||||
|
||||
// MARK: select animation
|
||||
|
||||
func playLabelAnimation(_ textLabel: UILabel) {
|
||||
|
||||
let yPositionAnimation = createAnimation(Constants.AnimationKeys.PositionY, values:[textLabel.center.y as AnyObject, (textLabel.center.y - 60.0) as AnyObject], duration:duration)
|
||||
yPositionAnimation.fillMode = kCAFillModeRemoved
|
||||
yPositionAnimation.isRemovedOnCompletion = true
|
||||
textLabel.layer.add(yPositionAnimation, forKey: nil)
|
||||
|
||||
let scaleAnimation = createAnimation(Constants.AnimationKeys.Scale, values:[1.0 as AnyObject ,2.0 as AnyObject], duration:duration)
|
||||
scaleAnimation.fillMode = kCAFillModeRemoved
|
||||
scaleAnimation.isRemovedOnCompletion = true
|
||||
textLabel.layer.add(scaleAnimation, forKey: nil)
|
||||
|
||||
let opacityAnimation = createAnimation(Constants.AnimationKeys.Opacity, values:[1.0 as AnyObject ,0.0 as AnyObject], duration:duration)
|
||||
textLabel.layer.add(opacityAnimation, forKey: nil)
|
||||
}
|
||||
|
||||
func createAnimation(_ keyPath: String, values: [AnyObject], duration: CGFloat)->CAKeyframeAnimation {
|
||||
|
||||
let animation = CAKeyframeAnimation(keyPath: keyPath)
|
||||
animation.values = values
|
||||
animation.duration = TimeInterval(duration)
|
||||
animation.calculationMode = kCAAnimationCubic
|
||||
animation.fillMode = kCAFillModeForwards
|
||||
animation.isRemovedOnCompletion = false
|
||||
return animation
|
||||
}
|
||||
|
||||
// MARK: deselect animation
|
||||
|
||||
func playDeselectLabelAnimation(_ textLabel: UILabel) {
|
||||
|
||||
let yPositionAnimation = createAnimation(Constants.AnimationKeys.PositionY, values:[(textLabel.center.y + 15) as AnyObject, textLabel.center.y as AnyObject], duration:duration)
|
||||
textLabel.layer.add(yPositionAnimation, forKey: nil)
|
||||
|
||||
let opacityAnimation = createAnimation(Constants.AnimationKeys.Opacity, values:[0 as AnyObject, 1 as AnyObject], duration:duration)
|
||||
textLabel.layer.add(opacityAnimation, forKey: nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,111 +20,110 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
import UIKit
|
||||
import QuartzCore
|
||||
import UIKit
|
||||
|
||||
/// The RAMRotationAnimation class provides rotation animation.
|
||||
open class RAMRotationAnimation : RAMItemAnimation {
|
||||
|
||||
/**
|
||||
Animation direction
|
||||
|
||||
- Left: left direction
|
||||
- Right: right direction
|
||||
*/
|
||||
public enum RAMRotationDirection {
|
||||
case left
|
||||
case right
|
||||
}
|
||||
/// Animation direction (left, right)
|
||||
open var direction : RAMRotationDirection!
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is selected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
override open func playAnimation(_ icon : UIImageView, textLabel : UILabel) {
|
||||
playRoatationAnimation(icon)
|
||||
textLabel.textColor = textSelectedColor
|
||||
}
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is unselected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
- parameter defaultTextColor: default UITabBarItem text color
|
||||
- parameter defaultIconColor: default UITabBarItem icon color
|
||||
*/
|
||||
override open func deselectAnimation(_ icon : UIImageView, textLabel : UILabel, defaultTextColor : UIColor, defaultIconColor : UIColor) {
|
||||
textLabel.textColor = defaultTextColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderMode = defaultIconColor.cgColor.alpha == 0 ? UIImageRenderingMode.alwaysOriginal :
|
||||
UIImageRenderingMode.alwaysTemplate
|
||||
let renderImage = iconImage.withRenderingMode(renderMode)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = defaultIconColor
|
||||
open class RAMRotationAnimation: RAMItemAnimation {
|
||||
|
||||
/**
|
||||
Animation direction
|
||||
|
||||
- Left: left direction
|
||||
- Right: right direction
|
||||
*/
|
||||
public enum RAMRotationDirection {
|
||||
case left
|
||||
case right
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Method call when TabBarController did load
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
override open func selectedState(_ icon : UIImageView, textLabel : UILabel) {
|
||||
textLabel.textColor = textSelectedColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = textSelectedColor
|
||||
|
||||
/// Animation direction (left, right)
|
||||
open var direction: RAMRotationDirection!
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is selected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open override func playAnimation(_ icon: UIImageView, textLabel: UILabel) {
|
||||
playRoatationAnimation(icon)
|
||||
textLabel.textColor = textSelectedColor
|
||||
}
|
||||
}
|
||||
|
||||
func playRoatationAnimation(_ icon : UIImageView) {
|
||||
|
||||
let rotateAnimation = CABasicAnimation(keyPath: Constants.AnimationKeys.Rotation)
|
||||
rotateAnimation.fromValue = 0.0
|
||||
|
||||
var toValue = CGFloat.pi * 2
|
||||
if direction != nil && direction == RAMRotationDirection.left {
|
||||
toValue = toValue * -1.0
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is unselected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
- parameter defaultTextColor: default UITabBarItem text color
|
||||
- parameter defaultIconColor: default UITabBarItem icon color
|
||||
*/
|
||||
open override func deselectAnimation(_ icon: UIImageView, textLabel: UILabel, defaultTextColor: UIColor, defaultIconColor: UIColor) {
|
||||
textLabel.textColor = defaultTextColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderMode = defaultIconColor.cgColor.alpha == 0 ? UIImage.RenderingMode.alwaysOriginal :
|
||||
UIImage.RenderingMode.alwaysTemplate
|
||||
let renderImage = iconImage.withRenderingMode(renderMode)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = defaultIconColor
|
||||
}
|
||||
}
|
||||
|
||||
rotateAnimation.toValue = toValue
|
||||
rotateAnimation.duration = TimeInterval(duration)
|
||||
|
||||
icon.layer.add(rotateAnimation, forKey: nil)
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = iconSelectedColor
|
||||
|
||||
/**
|
||||
Method call when TabBarController did load
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open override func selectedState(_ icon: UIImageView, textLabel: UILabel) {
|
||||
textLabel.textColor = textSelectedColor
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = iconSelectedColor
|
||||
}
|
||||
}
|
||||
|
||||
func playRoatationAnimation(_ icon: UIImageView) {
|
||||
|
||||
let rotateAnimation = CABasicAnimation(keyPath: Constants.AnimationKeys.rotation)
|
||||
rotateAnimation.fromValue = 0.0
|
||||
|
||||
var toValue = CGFloat.pi * 2
|
||||
if direction != nil && direction == RAMRotationDirection.left {
|
||||
toValue = toValue * -1.0
|
||||
}
|
||||
|
||||
rotateAnimation.toValue = toValue
|
||||
rotateAnimation.duration = TimeInterval(duration)
|
||||
|
||||
icon.layer.add(rotateAnimation, forKey: nil)
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = iconSelectedColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The RAMLeftRotationAnimation class provides letf rotation animation.
|
||||
class RAMLeftRotationAnimation : RAMRotationAnimation {
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
direction = RAMRotationDirection.left
|
||||
}
|
||||
open class RAMLeftRotationAnimation: RAMRotationAnimation {
|
||||
|
||||
public override init() {
|
||||
super.init()
|
||||
direction = RAMRotationDirection.left
|
||||
}
|
||||
}
|
||||
|
||||
/// The RAMRightRotationAnimation class provides rigth rotation animation.
|
||||
class RAMRightRotationAnimation : RAMRotationAnimation {
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
direction = RAMRotationDirection.right
|
||||
}
|
||||
open class RAMRightRotationAnimation: RAMRotationAnimation {
|
||||
|
||||
public override init() {
|
||||
super.init()
|
||||
direction = RAMRotationDirection.right
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,109 +23,107 @@
|
||||
import UIKit
|
||||
|
||||
/// Transition animtion
|
||||
open class RAMTransitionItemAnimations : RAMItemAnimation {
|
||||
|
||||
/// Options for animating. Default TransitionNone
|
||||
open var transitionOptions : UIViewAnimationOptions!
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
transitionOptions = UIViewAnimationOptions()
|
||||
}
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is selected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
override open func playAnimation(_ icon : UIImageView, textLabel : UILabel) {
|
||||
|
||||
selectedColor(icon, textLabel: textLabel)
|
||||
|
||||
UIView.transition(with: icon, duration: TimeInterval(duration), options: transitionOptions, animations: {
|
||||
}, completion: { _ in
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is unselected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
- parameter defaultTextColor: default UITabBarItem text color
|
||||
- parameter defaultIconColor: default UITabBarItem icon color
|
||||
*/
|
||||
override open func deselectAnimation(_ icon : UIImageView, textLabel : UILabel, defaultTextColor : UIColor, defaultIconColor : UIColor) {
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderMode = defaultIconColor.cgColor.alpha == 0 ? UIImageRenderingMode.alwaysOriginal :
|
||||
UIImageRenderingMode.alwaysTemplate
|
||||
let renderImage = iconImage.withRenderingMode(renderMode)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = defaultIconColor
|
||||
open class RAMTransitionItemAnimations: RAMItemAnimation {
|
||||
|
||||
/// Options for animating. Default TransitionNone
|
||||
open var transitionOptions: UIView.AnimationOptions!
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
transitionOptions = UIView.AnimationOptions()
|
||||
}
|
||||
textLabel.textColor = defaultTextColor
|
||||
}
|
||||
|
||||
/**
|
||||
Method call when TabBarController did load
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
override open func selectedState(_ icon : UIImageView, textLabel : UILabel) {
|
||||
|
||||
selectedColor(icon, textLabel: textLabel)
|
||||
}
|
||||
|
||||
|
||||
func selectedColor(_ icon : UIImageView, textLabel : UILabel) {
|
||||
|
||||
if let iconImage = icon.image , iconSelectedColor != nil {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = iconSelectedColor
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is selected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open override func playAnimation(_ icon: UIImageView, textLabel: UILabel) {
|
||||
|
||||
selectedColor(icon, textLabel: textLabel)
|
||||
|
||||
UIView.transition(with: icon, duration: TimeInterval(duration), options: transitionOptions, animations: {
|
||||
}, completion: { _ in
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is unselected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
- parameter defaultTextColor: default UITabBarItem text color
|
||||
- parameter defaultIconColor: default UITabBarItem icon color
|
||||
*/
|
||||
open override func deselectAnimation(_ icon: UIImageView, textLabel: UILabel, defaultTextColor: UIColor, defaultIconColor: UIColor) {
|
||||
|
||||
if let iconImage = icon.image {
|
||||
let renderMode = defaultIconColor.cgColor.alpha == 0 ? UIImage.RenderingMode.alwaysOriginal :
|
||||
UIImage.RenderingMode.alwaysTemplate
|
||||
let renderImage = iconImage.withRenderingMode(renderMode)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = defaultIconColor
|
||||
}
|
||||
textLabel.textColor = defaultTextColor
|
||||
}
|
||||
|
||||
/**
|
||||
Method call when TabBarController did load
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open override func selectedState(_ icon: UIImageView, textLabel: UILabel) {
|
||||
|
||||
selectedColor(icon, textLabel: textLabel)
|
||||
}
|
||||
|
||||
func selectedColor(_ icon: UIImageView, textLabel: UILabel) {
|
||||
|
||||
if let iconImage = icon.image, iconSelectedColor != nil {
|
||||
let renderImage = iconImage.withRenderingMode(.alwaysTemplate)
|
||||
icon.image = renderImage
|
||||
icon.tintColor = iconSelectedColor
|
||||
}
|
||||
|
||||
textLabel.textColor = textSelectedColor
|
||||
}
|
||||
|
||||
textLabel.textColor = textSelectedColor
|
||||
}
|
||||
}
|
||||
|
||||
class RAMFlipLeftTransitionItemAnimations : RAMTransitionItemAnimations {
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
transitionOptions = UIViewAnimationOptions.transitionFlipFromLeft
|
||||
}
|
||||
open class RAMFlipLeftTransitionItemAnimations: RAMTransitionItemAnimations {
|
||||
|
||||
public override init() {
|
||||
super.init()
|
||||
|
||||
transitionOptions = UIView.AnimationOptions.transitionFlipFromLeft
|
||||
}
|
||||
}
|
||||
|
||||
open class RAMFlipRightTransitionItemAnimations: RAMTransitionItemAnimations {
|
||||
|
||||
class RAMFlipRightTransitionItemAnimations : RAMTransitionItemAnimations {
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
transitionOptions = UIViewAnimationOptions.transitionFlipFromRight
|
||||
}
|
||||
public override init() {
|
||||
super.init()
|
||||
|
||||
transitionOptions = UIView.AnimationOptions.transitionFlipFromRight
|
||||
}
|
||||
}
|
||||
|
||||
class RAMFlipTopTransitionItemAnimations : RAMTransitionItemAnimations {
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
transitionOptions = UIViewAnimationOptions.transitionFlipFromTop
|
||||
}
|
||||
open class RAMFlipTopTransitionItemAnimations: RAMTransitionItemAnimations {
|
||||
|
||||
public override init() {
|
||||
super.init()
|
||||
|
||||
transitionOptions = UIView.AnimationOptions.transitionFlipFromTop
|
||||
}
|
||||
}
|
||||
|
||||
class RAMFlipBottomTransitionItemAnimations : RAMTransitionItemAnimations {
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
transitionOptions = UIViewAnimationOptions.transitionFlipFromBottom
|
||||
}
|
||||
open class RAMFlipBottomTransitionItemAnimations: RAMTransitionItemAnimations {
|
||||
|
||||
public override init() {
|
||||
super.init()
|
||||
|
||||
transitionOptions = UIView.AnimationOptions.transitionFlipFromBottom
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
// Copyright (c) 03/05/2018. Ramotion Inc. (http://ramotion.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
extension RAMAnimatedTabBarController {
|
||||
|
||||
func createBottomLine() {
|
||||
guard let currentItem = containers.first else { return }
|
||||
|
||||
let container = UIView()
|
||||
container.backgroundColor = .clear
|
||||
container.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
view.addSubview(container)
|
||||
|
||||
container.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
|
||||
container.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
|
||||
container.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
|
||||
container.heightAnchor.constraint(equalToConstant: bottomLineHeight).isActive = true
|
||||
|
||||
|
||||
let line = UIView()
|
||||
line.backgroundColor = bottomLineColor
|
||||
line.translatesAutoresizingMaskIntoConstraints = false
|
||||
container.addSubview(line)
|
||||
bottomLine = line
|
||||
|
||||
lineLeadingConstraint = bottomLine?.leadingAnchor.constraint(equalTo: currentItem.leadingAnchor)
|
||||
lineLeadingConstraint?.isActive = true
|
||||
|
||||
lineHeightConstraint = bottomLine?.heightAnchor.constraint(equalToConstant: bottomLineHeight)
|
||||
lineHeightConstraint?.isActive = true
|
||||
|
||||
// add constraints
|
||||
bottomLine?.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
|
||||
bottomLine?.widthAnchor.constraint(equalTo: currentItem.widthAnchor).isActive = true
|
||||
}
|
||||
|
||||
func removeBottomLine() {
|
||||
guard let bottomLine = self.bottomLine else { return }
|
||||
|
||||
bottomLine.superview?.removeFromSuperview()
|
||||
self.bottomLine = nil
|
||||
lineLeadingConstraint?.isActive = false
|
||||
lineLeadingConstraint = nil
|
||||
}
|
||||
|
||||
func setBottomLinePosition(index: Int, animated: Bool = true) {
|
||||
guard let itemsCount = tabBar.items?.count, itemsCount > index,
|
||||
let currentItem = containers.at(index) else { return }
|
||||
|
||||
lineLeadingConstraint?.isActive = false
|
||||
|
||||
lineLeadingConstraint = bottomLine?.leadingAnchor.constraint(equalTo: currentItem.leadingAnchor)
|
||||
lineLeadingConstraint?.isActive = true
|
||||
|
||||
if animated {
|
||||
UIView.animate(withDuration: bottomLineMoveDuration) { self.bottomLine?.superview?.layoutIfNeeded() }
|
||||
} else {
|
||||
self.bottomLine?.superview?.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
func updateBottomLineHeight(to height: CGFloat) {
|
||||
lineHeightConstraint?.isActive = false
|
||||
|
||||
lineHeightConstraint = bottomLine?.heightAnchor.constraint(equalToConstant: height)
|
||||
lineHeightConstraint?.isActive = true
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// AnimationTabBarController.swift
|
||||
// RAMAnimatedTabBarController.swift
|
||||
//
|
||||
// Copyright (c) 11/10/14 Ramotion Inc. (http://ramotion.com)
|
||||
//
|
||||
@@ -22,453 +22,313 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
// MARK: Custom Badge
|
||||
|
||||
extension RAMAnimatedTabBarItem {
|
||||
|
||||
/// The current badge value
|
||||
override open var badgeValue: String? {
|
||||
get {
|
||||
return badge?.text
|
||||
}
|
||||
set(newValue) {
|
||||
|
||||
if newValue == nil {
|
||||
badge?.removeFromSuperview()
|
||||
badge = nil;
|
||||
return
|
||||
}
|
||||
|
||||
if let iconView = iconView, let contanerView = iconView.icon.superview , badge == nil {
|
||||
badge = RAMBadge.badge()
|
||||
badge!.addBadgeOnView(contanerView)
|
||||
}
|
||||
|
||||
badge?.text = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// UITabBarItem with animation
|
||||
open class RAMAnimatedTabBarItem: UITabBarItem {
|
||||
|
||||
@IBInspectable open var yOffSet: CGFloat = 0
|
||||
|
||||
open override var isEnabled: Bool {
|
||||
didSet {
|
||||
iconView?.icon.alpha = isEnabled == true ? 1 : 0.5
|
||||
iconView?.textLabel.alpha = isEnabled == true ? 1 : 0.5
|
||||
}
|
||||
}
|
||||
|
||||
/// animation for UITabBarItem. use RAMFumeAnimation, RAMBounceAnimation, RAMRotationAnimation, RAMFrameItemAnimation, RAMTransitionAnimation
|
||||
/// or create custom anmation inherit RAMItemAnimation
|
||||
@IBOutlet open var animation: RAMItemAnimation!
|
||||
|
||||
/// The font used to render the UITabBarItem text.
|
||||
open var textFont: UIFont = UIFont.systemFont(ofSize: 10)
|
||||
|
||||
/// The color of the UITabBarItem text.
|
||||
@IBInspectable open var textColor: UIColor = UIColor.black
|
||||
|
||||
/// The tint color of the UITabBarItem icon.
|
||||
@IBInspectable open var iconColor: UIColor = UIColor.clear // if alpha color is 0 color ignoring
|
||||
|
||||
open var bgDefaultColor: UIColor = UIColor.clear // background color
|
||||
open var bgSelectedColor: UIColor = UIColor.clear
|
||||
|
||||
// The current badge value
|
||||
open var badge: RAMBadge? // use badgeValue to show badge
|
||||
|
||||
// Container for icon and text in UITableItem.
|
||||
open var iconView: (icon: UIImageView, textLabel: UILabel)?
|
||||
|
||||
/**
|
||||
Start selected animation
|
||||
*/
|
||||
open func playAnimation() {
|
||||
|
||||
assert(animation != nil, "add animation in UITabBarItem")
|
||||
guard animation != nil && iconView != nil else {
|
||||
return
|
||||
}
|
||||
animation.playAnimation(iconView!.icon, textLabel: iconView!.textLabel)
|
||||
}
|
||||
|
||||
/**
|
||||
Start unselected animation
|
||||
*/
|
||||
open func deselectAnimation() {
|
||||
|
||||
guard animation != nil && iconView != nil else {
|
||||
return
|
||||
}
|
||||
|
||||
animation.deselectAnimation(
|
||||
iconView!.icon,
|
||||
textLabel: iconView!.textLabel,
|
||||
defaultTextColor: textColor,
|
||||
defaultIconColor: iconColor)
|
||||
}
|
||||
|
||||
/**
|
||||
Set selected state without animation
|
||||
*/
|
||||
open func selectedState() {
|
||||
guard animation != nil && iconView != nil else {
|
||||
return
|
||||
}
|
||||
|
||||
animation.selectedState(iconView!.icon, textLabel: iconView!.textLabel)
|
||||
}
|
||||
}
|
||||
|
||||
extension RAMAnimatedTabBarController {
|
||||
|
||||
/**
|
||||
Change selected color for each UITabBarItem
|
||||
|
||||
- parameter textSelectedColor: set new color for text
|
||||
- parameter iconSelectedColor: set new color for icon
|
||||
*/
|
||||
open func changeSelectedColor(_ textSelectedColor:UIColor, iconSelectedColor:UIColor) {
|
||||
|
||||
let items = tabBar.items as! [RAMAnimatedTabBarItem]
|
||||
for index in 0..<items.count {
|
||||
let item = items[index]
|
||||
|
||||
item.animation.textSelectedColor = textSelectedColor
|
||||
item.animation.iconSelectedColor = iconSelectedColor
|
||||
|
||||
if item == self.tabBar.selectedItem {
|
||||
item.selectedState()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Hide UITabBarController
|
||||
|
||||
- parameter isHidden: A Boolean indicating whether the UITabBarController is displayed
|
||||
*/
|
||||
open func animationTabBarHidden(_ isHidden:Bool) {
|
||||
guard let items = tabBar.items as? [RAMAnimatedTabBarItem] else {
|
||||
fatalError("items must inherit RAMAnimatedTabBarItem")
|
||||
}
|
||||
for item in items {
|
||||
if let iconView = item.iconView {
|
||||
iconView.icon.superview?.isHidden = isHidden
|
||||
}
|
||||
}
|
||||
self.tabBar.isHidden = isHidden;
|
||||
}
|
||||
|
||||
/**
|
||||
Selected UITabBarItem with animaton
|
||||
|
||||
- parameter from: Index for unselected animation
|
||||
- parameter to: Index for selected animation
|
||||
*/
|
||||
open func setSelectIndex(from: Int, to: Int) {
|
||||
selectedIndex = to
|
||||
guard let items = tabBar.items as? [RAMAnimatedTabBarItem] else {
|
||||
fatalError("items must inherit RAMAnimatedTabBarItem")
|
||||
}
|
||||
|
||||
let containerFrom = items[from].iconView?.icon.superview
|
||||
containerFrom?.backgroundColor = items[from].bgDefaultColor
|
||||
items[from].deselectAnimation()
|
||||
|
||||
let containerTo = items[to].iconView?.icon.superview
|
||||
containerTo?.backgroundColor = items[to].bgSelectedColor
|
||||
items[to].playAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
/// UITabBarController with item animations
|
||||
open class RAMAnimatedTabBarController: UITabBarController {
|
||||
|
||||
fileprivate var didInit: Bool = false
|
||||
fileprivate var didLoadView: Bool = false
|
||||
|
||||
// MARK: life circle
|
||||
|
||||
/**
|
||||
Returns a newly initialized view controller with the nib file in the specified bundle.
|
||||
|
||||
- parameter nibNameOrNil: The name of the nib file to associate with the view controller. The nib file name should
|
||||
not contain any leading path information. If you specify nil, the nibName property is set to nil.
|
||||
|
||||
- parameter nibBundleOrNil: The bundle in which to search for the nib file. This method looks for the nib file in the
|
||||
bundle's language-specific project directories first, followed by the Resources directory. If this parameter is nil,
|
||||
the method uses the heuristics described below to locate the nib file.
|
||||
|
||||
- returns: A newly initialized RAMAnimatedTabBarController object.
|
||||
*/
|
||||
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
|
||||
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
|
||||
|
||||
self.didInit = true
|
||||
self.initializeContainers()
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a newly initialized view controller with the nib file in the specified bundle.
|
||||
|
||||
- parameter viewControllers: Sets the root view controllers of the tab bar controller.
|
||||
|
||||
- returns: A newly initialized RAMAnimatedTabBarController object.
|
||||
*/
|
||||
public init(viewControllers: [UIViewController]) {
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
self.didInit = true
|
||||
|
||||
// Set initial items
|
||||
self.setViewControllers(viewControllers, animated: false)
|
||||
|
||||
self.initializeContainers()
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a newly initialized view controller with the nib file in the specified bundle.
|
||||
|
||||
- parameter aDecoder: An unarchiver object.
|
||||
|
||||
- returns: A newly initialized RAMAnimatedTabBarController object.
|
||||
*/
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
self.didInit = true
|
||||
self.initializeContainers()
|
||||
}
|
||||
|
||||
override open func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
self.didLoadView = true
|
||||
|
||||
self.initializeContainers()
|
||||
}
|
||||
|
||||
fileprivate func initializeContainers() {
|
||||
if !self.didInit || !self.didLoadView {
|
||||
return
|
||||
/**
|
||||
The animated items displayed by the tab bar.
|
||||
**/
|
||||
open var animatedItems: [RAMAnimatedTabBarItem] {
|
||||
return tabBar.items as? [RAMAnimatedTabBarItem] ?? []
|
||||
}
|
||||
|
||||
let containers = self.createViewContainers()
|
||||
|
||||
self.createCustomIcons(containers)
|
||||
}
|
||||
|
||||
// MARK: create methods
|
||||
|
||||
fileprivate func createCustomIcons(_ containers : NSDictionary) {
|
||||
|
||||
guard let items = tabBar.items as? [RAMAnimatedTabBarItem] else {
|
||||
fatalError("items must inherit RAMAnimatedTabBarItem")
|
||||
/**
|
||||
Show bottom line for indicating selected item, default value is false
|
||||
**/
|
||||
open var isBottomLineShow: Bool = false {
|
||||
didSet {
|
||||
if isBottomLineShow {
|
||||
if bottomLine == nil { createBottomLine() }
|
||||
} else {
|
||||
if bottomLine != nil { removeBottomLine() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var index = 0
|
||||
for item in items {
|
||||
|
||||
guard let itemImage = item.image else {
|
||||
fatalError("add image icon in UITabBarItem")
|
||||
}
|
||||
|
||||
guard let container = containers["container\(items.count - 1 - index)"] as? UIView else {
|
||||
fatalError()
|
||||
}
|
||||
container.tag = index
|
||||
|
||||
|
||||
let renderMode = item.iconColor.cgColor.alpha == 0 ? UIImageRenderingMode.alwaysOriginal :
|
||||
UIImageRenderingMode.alwaysTemplate
|
||||
|
||||
let icon = UIImageView(image: item.image?.withRenderingMode(renderMode))
|
||||
icon.translatesAutoresizingMaskIntoConstraints = false
|
||||
icon.tintColor = item.iconColor
|
||||
|
||||
// text
|
||||
let textLabel = UILabel()
|
||||
textLabel.text = item.title
|
||||
textLabel.backgroundColor = UIColor.clear
|
||||
textLabel.textColor = item.textColor
|
||||
textLabel.font = item.textFont
|
||||
textLabel.textAlignment = NSTextAlignment.center
|
||||
textLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
container.backgroundColor = (items as [RAMAnimatedTabBarItem])[index].bgDefaultColor
|
||||
|
||||
container.addSubview(icon)
|
||||
createConstraints(icon, container: container, size: itemImage.size, yOffset: -5 - item.yOffSet)
|
||||
|
||||
container.addSubview(textLabel)
|
||||
let textLabelWidth = tabBar.frame.size.width / CGFloat(items.count) - 5.0
|
||||
createConstraints(textLabel, container: container, width: textLabelWidth, yOffset: 16 - item.yOffSet)
|
||||
|
||||
if item.isEnabled == false {
|
||||
icon.alpha = 0.5
|
||||
textLabel.alpha = 0.5
|
||||
}
|
||||
item.iconView = (icon:icon, textLabel:textLabel)
|
||||
|
||||
if 0 == index { // selected first elemet
|
||||
item.selectedState()
|
||||
container.backgroundColor = (items as [RAMAnimatedTabBarItem])[index].bgSelectedColor
|
||||
}
|
||||
|
||||
item.image = nil
|
||||
item.title = ""
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func createConstraints(_ view: UIView, container: UIView, size: CGSize, yOffset: CGFloat) {
|
||||
createConstraints(view, container: container, width: size.width, height: size.height, yOffset: yOffset)
|
||||
}
|
||||
|
||||
fileprivate func createConstraints(_ view:UIView, container:UIView, width: CGFloat? = nil, height: CGFloat? = nil, yOffset:CGFloat) {
|
||||
|
||||
let constX = NSLayoutConstraint(item: view,
|
||||
attribute: NSLayoutAttribute.centerX,
|
||||
relatedBy: NSLayoutRelation.equal,
|
||||
toItem: container,
|
||||
attribute: NSLayoutAttribute.centerX,
|
||||
multiplier: 1,
|
||||
constant: 0)
|
||||
container.addConstraint(constX)
|
||||
|
||||
let constY = NSLayoutConstraint(item: view,
|
||||
attribute: NSLayoutAttribute.centerY,
|
||||
relatedBy: NSLayoutRelation.equal,
|
||||
toItem: container,
|
||||
attribute: NSLayoutAttribute.centerY,
|
||||
multiplier: 1,
|
||||
constant: yOffset)
|
||||
container.addConstraint(constY)
|
||||
|
||||
if let width = width {
|
||||
let constW = NSLayoutConstraint(item: view,
|
||||
attribute: NSLayoutAttribute.width,
|
||||
relatedBy: NSLayoutRelation.equal,
|
||||
toItem: nil,
|
||||
attribute: NSLayoutAttribute.notAnAttribute,
|
||||
multiplier: 1,
|
||||
constant: width)
|
||||
view.addConstraint(constW)
|
||||
/**
|
||||
Bottom line color
|
||||
**/
|
||||
open var bottomLineColor: UIColor = .black {
|
||||
didSet {
|
||||
bottomLine?.backgroundColor = bottomLineColor
|
||||
}
|
||||
}
|
||||
|
||||
if let height = height {
|
||||
let constH = NSLayoutConstraint(item: view,
|
||||
attribute: NSLayoutAttribute.height,
|
||||
relatedBy: NSLayoutRelation.equal,
|
||||
toItem: nil,
|
||||
attribute: NSLayoutAttribute.notAnAttribute,
|
||||
multiplier: 1,
|
||||
constant: height)
|
||||
view.addConstraint(constH)
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func createViewContainers() -> NSDictionary {
|
||||
|
||||
guard let items = tabBar.items else {
|
||||
fatalError("add items in tabBar")
|
||||
/**
|
||||
Bottom line height
|
||||
**/
|
||||
open var bottomLineHeight: CGFloat = 2 {
|
||||
didSet {
|
||||
if bottomLineHeight > 0 {
|
||||
updateBottomLineHeight(to: bottomLineHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var containersDict = [String: AnyObject]()
|
||||
/**
|
||||
Bottom line time of animations duration
|
||||
**/
|
||||
open var bottomLineMoveDuration: TimeInterval = 0.3
|
||||
|
||||
private(set) var containers: [UIView] = []
|
||||
|
||||
for index in 0..<items.count {
|
||||
let viewContainer = createViewContainer()
|
||||
containersDict["container\(index)"] = viewContainer
|
||||
open override var viewControllers: [UIViewController]? {
|
||||
didSet {
|
||||
initializeContainers()
|
||||
}
|
||||
}
|
||||
|
||||
var formatString = "H:|-(0)-[container0]"
|
||||
for index in 1..<items.count {
|
||||
formatString += "-(0)-[container\(index)(==container0)]"
|
||||
}
|
||||
formatString += "-(0)-|"
|
||||
let constranints = NSLayoutConstraint.constraints(withVisualFormat: formatString,
|
||||
options:NSLayoutFormatOptions.directionRightToLeft,
|
||||
metrics: nil,
|
||||
views: (containersDict as [String : AnyObject]))
|
||||
view.addConstraints(constranints)
|
||||
|
||||
return containersDict as NSDictionary
|
||||
}
|
||||
|
||||
fileprivate func createViewContainer() -> UIView {
|
||||
let viewContainer = UIView();
|
||||
viewContainer.backgroundColor = UIColor.clear // for test
|
||||
viewContainer.translatesAutoresizingMaskIntoConstraints = false
|
||||
viewContainer.isExclusiveTouch = true
|
||||
view.addSubview(viewContainer)
|
||||
|
||||
// add gesture
|
||||
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(RAMAnimatedTabBarController.tapHandler(_:)))
|
||||
tapGesture.numberOfTouchesRequired = 1
|
||||
viewContainer.addGestureRecognizer(tapGesture)
|
||||
|
||||
// add constrains
|
||||
viewContainer.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor).isActive = true
|
||||
|
||||
let constH = NSLayoutConstraint(item: viewContainer,
|
||||
attribute: NSLayoutAttribute.height,
|
||||
relatedBy: NSLayoutRelation.equal,
|
||||
toItem: nil,
|
||||
attribute: NSLayoutAttribute.notAnAttribute,
|
||||
multiplier: 1,
|
||||
constant: tabBar.frame.size.height)
|
||||
viewContainer.addConstraint(constH)
|
||||
|
||||
return viewContainer
|
||||
}
|
||||
|
||||
// MARK: actions
|
||||
|
||||
open func tapHandler(_ gesture:UIGestureRecognizer) {
|
||||
|
||||
guard let items = tabBar.items as? [RAMAnimatedTabBarItem],
|
||||
let gestureView = gesture.view else {
|
||||
fatalError("items must inherit RAMAnimatedTabBarItem")
|
||||
open override func setViewControllers(_ viewControllers: [UIViewController]?, animated: Bool) {
|
||||
super.setViewControllers(viewControllers, animated: animated)
|
||||
initializeContainers()
|
||||
}
|
||||
|
||||
let currentIndex = gestureView.tag
|
||||
|
||||
if items[currentIndex].isEnabled == false { return }
|
||||
|
||||
let controller = self.childViewControllers[currentIndex]
|
||||
|
||||
if let shouldSelect = delegate?.tabBarController?(self, shouldSelect: controller)
|
||||
, !shouldSelect {
|
||||
return
|
||||
open override var selectedIndex: Int {
|
||||
didSet {
|
||||
self.setBottomLinePosition(index: selectedIndex)
|
||||
}
|
||||
}
|
||||
|
||||
open override var selectedViewController: UIViewController? {
|
||||
willSet {
|
||||
guard let vc = newValue,
|
||||
let index = viewControllers?.firstIndex(of: vc) else { return }
|
||||
handleSelection(index: index)
|
||||
}
|
||||
}
|
||||
|
||||
if selectedIndex != currentIndex {
|
||||
let animationItem : RAMAnimatedTabBarItem = items[currentIndex]
|
||||
animationItem.playAnimation()
|
||||
|
||||
let deselectItem = items[selectedIndex]
|
||||
|
||||
let containerPrevious : UIView = deselectItem.iconView!.icon.superview!
|
||||
containerPrevious.backgroundColor = items[currentIndex].bgDefaultColor
|
||||
|
||||
deselectItem.deselectAnimation()
|
||||
|
||||
let container : UIView = animationItem.iconView!.icon.superview!
|
||||
container.backgroundColor = items[currentIndex].bgSelectedColor
|
||||
|
||||
selectedIndex = gestureView.tag
|
||||
delegate?.tabBarController?(self, didSelect: controller)
|
||||
|
||||
} else if selectedIndex == currentIndex {
|
||||
|
||||
if let navVC = self.viewControllers![selectedIndex] as? UINavigationController {
|
||||
navVC.popToRootViewController(animated: true)
|
||||
}
|
||||
var lineHeightConstraint: NSLayoutConstraint?
|
||||
var lineLeadingConstraint: NSLayoutConstraint?
|
||||
var bottomLine: UIView?
|
||||
var arrBottomAnchor:[NSLayoutConstraint] = []
|
||||
var arrViews: [UIView] = []
|
||||
|
||||
/**
|
||||
Hide UITabBar
|
||||
|
||||
- parameter isHidden: A Boolean indicating whether the UITabBarController is displayed
|
||||
*/
|
||||
@available(*, deprecated, message: "Now you can use UITabBar isHidden")
|
||||
open func animationTabBarHidden(_ isHidden: Bool) {
|
||||
tabBar.isHidden = isHidden
|
||||
}
|
||||
|
||||
// MARK: life circle
|
||||
|
||||
open override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
initializeContainers()
|
||||
}
|
||||
|
||||
override open func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
|
||||
coordinator.animate(alongsideTransition: { (transitionCoordinatorContext) -> Void in
|
||||
self.layoutContainers()
|
||||
}, completion: { (transitionCoordinatorContext) -> Void in
|
||||
//refresh view once rotation is completed not in will transition as it returns incorrect frame size.Refresh here
|
||||
})
|
||||
super.viewWillTransition(to: size, with: coordinator)
|
||||
}
|
||||
|
||||
// MARK: create methods
|
||||
private func initializeContainers() {
|
||||
containers.forEach { $0.removeFromSuperview() }
|
||||
containers.removeAll()
|
||||
|
||||
guard let items = tabBar.items else { return }
|
||||
guard items.count <= 5 else { fatalError("More button not supported") }
|
||||
|
||||
for index in 0 ..< items.count {
|
||||
let viewContainer = UIView()
|
||||
viewContainer.isExclusiveTouch = true
|
||||
viewContainer.tag = index
|
||||
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(itemTap))
|
||||
viewContainer.addGestureRecognizer(tapGesture)
|
||||
tabBar.addSubview(viewContainer)
|
||||
containers.append(viewContainer)
|
||||
}
|
||||
|
||||
if !containers.isEmpty {
|
||||
createCustomIcons(containers: containers)
|
||||
}
|
||||
|
||||
layoutContainers()
|
||||
}
|
||||
|
||||
private func layoutContainers() {
|
||||
let itemWidth = tabBar.bounds.width / CGFloat(containers.count)
|
||||
let isRTL = tabBar.userInterfaceLayoutDirection == .rightToLeft
|
||||
|
||||
for (index, container) in containers.enumerated() {
|
||||
let i = isRTL ? (containers.count - 1 - index) : index
|
||||
let frame = CGRect(x: itemWidth * CGFloat(i), y: 0, width: itemWidth, height: Theme.tabBarHeight)
|
||||
container.frame = frame
|
||||
|
||||
if let item = tabBar.items?.at(index) as? RAMAnimatedTabBarItem {
|
||||
let iconView = item.iconView?.icon
|
||||
let iconSize = iconView?.image?.size ?? CGSize(width: 30, height: 30)
|
||||
let iconX = (container.frame.width - iconSize.width) / 2 + item.titlePositionAdjustment.horizontal
|
||||
let iconY = (container.frame.height - iconSize.height) / 2 + Theme.defaultIconVerticalOffset + item.titlePositionAdjustment.vertical
|
||||
iconView?.frame = CGRect(x: iconX, y: iconY, width: iconSize.width, height: iconSize.height)
|
||||
|
||||
let label = item.iconView?.textLabel
|
||||
let labelSize = label?.sizeThatFits(CGSize.zero) ?? CGSize(width: tabBar.frame.size.width / CGFloat(containers.count), height: 20)
|
||||
let labelX = (container.frame.width - labelSize.width) / 2 + item.titlePositionAdjustment.horizontal
|
||||
let labelY = (container.frame.height) / 2 + Theme.defaultTitleVerticalOffset + item.titlePositionAdjustment.vertical
|
||||
label?.frame = CGRect(x: labelX, y: labelY, width: labelSize.width, height: labelSize.height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func createCustomIcons(containers: [UIView]) {
|
||||
guard let items = tabBar.items as? [RAMAnimatedTabBarItem] else {
|
||||
fatalError("items must inherit RAMAnimatedTabBarItem")
|
||||
}
|
||||
|
||||
for (index, item) in items.enumerated() {
|
||||
let container = containers[index]
|
||||
let renderMode = item.iconColor.cgColor.alpha == 0 ? UIImage.RenderingMode.alwaysOriginal :
|
||||
UIImage.RenderingMode.alwaysTemplate
|
||||
|
||||
|
||||
let iconImage = item.image ?? item.iconView?.icon.image
|
||||
let icon = UIImageView(image: iconImage?.withRenderingMode(renderMode))
|
||||
icon.tintColor = item.iconColor
|
||||
icon.highlightedImage = item.selectedImage?.withRenderingMode(renderMode)
|
||||
container.addSubview(icon)
|
||||
|
||||
|
||||
let textLabel = UILabel()
|
||||
if let title = item.title, !title.isEmpty {
|
||||
textLabel.text = title
|
||||
} else {
|
||||
textLabel.text = item.iconView?.textLabel.text
|
||||
}
|
||||
textLabel.backgroundColor = UIColor.clear
|
||||
textLabel.textColor = item.textColor
|
||||
textLabel.font = UIFont.systemFont(ofSize: item.textFontSize)
|
||||
textLabel.textAlignment = NSTextAlignment.center
|
||||
container.addSubview(textLabel)
|
||||
|
||||
|
||||
container.backgroundColor = (items as [RAMAnimatedTabBarItem])[index].bgDefaultColor
|
||||
if item.isEnabled == false {
|
||||
icon.alpha = 0.5
|
||||
textLabel.alpha = 0.5
|
||||
}
|
||||
item.iconView = (icon: icon, textLabel: textLabel)
|
||||
|
||||
if 0 == index { // selected first elemet
|
||||
item.selectedState()
|
||||
container.backgroundColor = (items as [RAMAnimatedTabBarItem])[index].bgSelectedColor
|
||||
} else {
|
||||
item.deselectedState()
|
||||
container.backgroundColor = (items as [RAMAnimatedTabBarItem])[index].bgDefaultColor
|
||||
}
|
||||
|
||||
item.image = nil
|
||||
item.title = ""
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: actions
|
||||
@objc private func itemTap(gesture: UITapGestureRecognizer) {
|
||||
guard let index = gesture.view?.tag else { return }
|
||||
handleSelection(index: index)
|
||||
}
|
||||
|
||||
private func handleSelection(index: Int) {
|
||||
guard let items = tabBar.items as? [RAMAnimatedTabBarItem] else { return }
|
||||
let currentIndex = index
|
||||
|
||||
if items[currentIndex].isEnabled == false { return }
|
||||
|
||||
let controller = children[currentIndex]
|
||||
|
||||
if let shouldSelect = delegate?.tabBarController?(self, shouldSelect: controller)
|
||||
, !shouldSelect {
|
||||
return
|
||||
}
|
||||
|
||||
if selectedIndex != currentIndex {
|
||||
let previousItem = items.at(selectedIndex)
|
||||
let previousContainer: UIView? = previousItem?.iconView?.icon.superview
|
||||
previousContainer?.backgroundColor = items[selectedIndex].bgDefaultColor
|
||||
previousItem?.deselectAnimation()
|
||||
|
||||
let currentItem: RAMAnimatedTabBarItem = items[currentIndex]
|
||||
currentItem.playAnimation()
|
||||
let currentContainer: UIView? = currentItem.iconView?.icon.superview
|
||||
currentContainer?.backgroundColor = items[currentIndex].bgSelectedColor
|
||||
|
||||
selectedIndex = index
|
||||
} else {
|
||||
if let navVC = viewControllers?[selectedIndex] as? UINavigationController {
|
||||
navVC.popToRootViewController(animated: true)
|
||||
}
|
||||
}
|
||||
delegate?.tabBarController?(self, didSelect: controller)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension RAMAnimatedTabBarController {
|
||||
|
||||
/**
|
||||
Change selected color for each UITabBarItem
|
||||
|
||||
- parameter textSelectedColor: set new color for text
|
||||
- parameter iconSelectedColor: set new color for icon
|
||||
*/
|
||||
open func changeSelectedColor(_ textSelectedColor: UIColor, iconSelectedColor: UIColor) {
|
||||
|
||||
let items = tabBar.items as! [RAMAnimatedTabBarItem]
|
||||
for index in 0 ..< items.count {
|
||||
let item = items[index]
|
||||
|
||||
item.animation.textSelectedColor = textSelectedColor
|
||||
item.animation.iconSelectedColor = iconSelectedColor
|
||||
|
||||
if item == tabBar.selectedItem {
|
||||
item.selectedState()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Selected UITabBarItem with animaton
|
||||
|
||||
- parameter from: Index for unselected animation
|
||||
- parameter to: Index for selected animation
|
||||
*/
|
||||
open func setSelectIndex(from: Int, to: Int) {
|
||||
selectedIndex = to
|
||||
guard let items = tabBar.items as? [RAMAnimatedTabBarItem] else {
|
||||
fatalError("items must inherit RAMAnimatedTabBarItem")
|
||||
}
|
||||
|
||||
let containerFrom = items[from].iconView?.icon.superview
|
||||
containerFrom?.backgroundColor = items[from].bgDefaultColor
|
||||
items[from].deselectAnimation()
|
||||
|
||||
let containerTo = items[to].iconView?.icon.superview
|
||||
containerTo?.backgroundColor = items[to].bgSelectedColor
|
||||
items[to].playAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension RAMAnimatedTabBarController {
|
||||
enum Theme {
|
||||
public static let tabBarHeight: CGFloat = 49
|
||||
public static let defaultTitleVerticalOffset: CGFloat = 10
|
||||
public static let defaultIconVerticalOffset: CGFloat = -5
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension UIView {
|
||||
var userInterfaceLayoutDirection: UIUserInterfaceLayoutDirection {
|
||||
return UIView.userInterfaceLayoutDirection(for: self.semanticContentAttribute)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
// RAMAnimatedTabBarItem.swift
|
||||
//
|
||||
// Copyright (c) 11/10/14 Ramotion Inc. (http://ramotion.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
/// UITabBarItem with animation
|
||||
open class RAMAnimatedTabBarItem: UITabBarItem {
|
||||
|
||||
open override var isEnabled: Bool {
|
||||
didSet {
|
||||
iconView?.icon.alpha = isEnabled == true ? 1 : 0.5
|
||||
iconView?.textLabel.alpha = isEnabled == true ? 1 : 0.5
|
||||
}
|
||||
}
|
||||
|
||||
/// Animation for UITabBarItem. Use RAMFumeAnimation, RAMBounceAnimation, RAMRotationAnimation, RAMFrameItemAnimation, RAMTransitionAnimation
|
||||
/// Also posible create custom anmation inherit from the RAMItemAnimation look for https://github.com/Ramotion/animated-tab-bar#creating-custom-animations
|
||||
@IBOutlet open var animation: RAMItemAnimation!
|
||||
|
||||
/// The font used to render the UITabBarItem text.
|
||||
@IBInspectable open var textFontSize: CGFloat = 10
|
||||
|
||||
/// The color of the UITabBarItem text.
|
||||
@IBInspectable open var textColor: UIColor = #colorLiteral(red: 0.5079551811, green: 0.5472556715, blue: 0.6011400746, alpha: 1)
|
||||
|
||||
/// The tint color of the UITabBarItem icon.
|
||||
@IBInspectable open var iconColor: UIColor = UIColor.clear // if alpha color is 0 color ignoring
|
||||
|
||||
open var bgDefaultColor: UIColor = UIColor.clear // background color
|
||||
open var bgSelectedColor: UIColor = UIColor.clear
|
||||
|
||||
// The current badge value
|
||||
open var badge: RAMBadge? // use badgeValue to show badge
|
||||
|
||||
// Container for icon and text in UITableItem.
|
||||
open var iconView: (icon: UIImageView, textLabel: UILabel)?
|
||||
|
||||
/**
|
||||
Start selected animation
|
||||
*/
|
||||
open func playAnimation() {
|
||||
|
||||
assert(animation != nil, "add animation in UITabBarItem")
|
||||
guard animation != nil, let iconView = iconView else {
|
||||
return
|
||||
}
|
||||
animation.playAnimation(iconView.icon, textLabel: iconView.textLabel)
|
||||
}
|
||||
|
||||
/**
|
||||
Start unselected animation
|
||||
*/
|
||||
open func deselectAnimation() {
|
||||
|
||||
guard animation != nil && iconView != nil else {
|
||||
return
|
||||
}
|
||||
|
||||
animation.deselectAnimation(
|
||||
iconView!.icon,
|
||||
textLabel: iconView!.textLabel,
|
||||
defaultTextColor: textColor,
|
||||
defaultIconColor: iconColor)
|
||||
}
|
||||
|
||||
/**
|
||||
Set selected state without animation
|
||||
*/
|
||||
open func selectedState() {
|
||||
guard animation != nil, let iconView = iconView else {
|
||||
return
|
||||
}
|
||||
|
||||
animation.selectedState(iconView.icon, textLabel: iconView.textLabel)
|
||||
}
|
||||
|
||||
/**
|
||||
Set deselected state without animation
|
||||
*/
|
||||
open func deselectedState() {
|
||||
guard animation != nil && iconView != nil else {
|
||||
return
|
||||
}
|
||||
|
||||
animation.deselectedState(iconView!.icon, textLabel: iconView!.textLabel)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Custom Badge
|
||||
extension RAMAnimatedTabBarItem {
|
||||
|
||||
/// The current badge value
|
||||
open override var badgeValue: String? {
|
||||
get {
|
||||
return badge?.text
|
||||
}
|
||||
set(newValue) {
|
||||
|
||||
if newValue == nil {
|
||||
badge?.removeFromSuperview()
|
||||
badge = nil
|
||||
return
|
||||
}
|
||||
|
||||
if let iconView = iconView, let contanerView = iconView.icon.superview, badge == nil {
|
||||
badge = RAMBadge.badge()
|
||||
badge?.addBadgeOnView(contanerView)
|
||||
}
|
||||
|
||||
badge?.text = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,101 +1,115 @@
|
||||
//
|
||||
// RAMBadge.swift
|
||||
// RAMAnimatedTabBarDemo
|
||||
//
|
||||
// Created by Alex K. on 17/12/15.
|
||||
// Copyright © 2015 Ramotion. All rights reserved.
|
||||
// Copyright (c) 17/12/15 Ramotion Inc. (http://ramotion.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
|
||||
import UIKit
|
||||
|
||||
open class RAMBadge: UILabel {
|
||||
|
||||
|
||||
internal var topConstraint: NSLayoutConstraint?
|
||||
internal var centerXConstraint: NSLayoutConstraint?
|
||||
|
||||
open class func badge() -> RAMBadge {
|
||||
return RAMBadge.init(frame: CGRect(x: 0, y: 0, width: 18, height: 18))
|
||||
return RAMBadge(frame: CGRect(x: 0, y: 0, width: 18, height: 18))
|
||||
}
|
||||
|
||||
override public init(frame: CGRect) {
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
layer.backgroundColor = UIColor.red.cgColor;
|
||||
layer.cornerRadius = frame.size.width / 2;
|
||||
|
||||
|
||||
layer.backgroundColor = UIColor.red.cgColor
|
||||
layer.cornerRadius = frame.size.width / 2
|
||||
|
||||
configureNumberLabel()
|
||||
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
|
||||
// constraints
|
||||
createSizeConstraints(frame.size)
|
||||
|
||||
}
|
||||
|
||||
override open var intrinsicContentSize: CGSize {
|
||||
|
||||
open override var intrinsicContentSize: CGSize {
|
||||
var contentSize = super.intrinsicContentSize
|
||||
contentSize.width += 10.0
|
||||
return contentSize
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
public required init?(coder _: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
// PRAGMA: create
|
||||
|
||||
|
||||
internal func createSizeConstraints(_ size: CGSize) {
|
||||
let widthConstraint = NSLayoutConstraint(
|
||||
item: self,
|
||||
attribute: NSLayoutAttribute.width,
|
||||
relatedBy: NSLayoutRelation.greaterThanOrEqual,
|
||||
attribute: .width,
|
||||
relatedBy: .greaterThanOrEqual,
|
||||
toItem: nil,
|
||||
attribute: NSLayoutAttribute.notAnAttribute,
|
||||
attribute: .notAnAttribute,
|
||||
multiplier: 1,
|
||||
constant: size.width)
|
||||
self.addConstraint(widthConstraint)
|
||||
addConstraint(widthConstraint)
|
||||
|
||||
|
||||
let heightConstraint = NSLayoutConstraint(
|
||||
item: self,
|
||||
attribute: NSLayoutAttribute.height,
|
||||
relatedBy: NSLayoutRelation.equal,
|
||||
attribute: .height,
|
||||
relatedBy: .equal,
|
||||
toItem: nil,
|
||||
attribute: NSLayoutAttribute.notAnAttribute,
|
||||
attribute: NSLayoutConstraint.Attribute.notAnAttribute,
|
||||
multiplier: 1,
|
||||
constant: size.height)
|
||||
self.addConstraint(heightConstraint)
|
||||
addConstraint(heightConstraint)
|
||||
}
|
||||
|
||||
fileprivate func configureNumberLabel() {
|
||||
|
||||
fileprivate func configureNumberLabel() {
|
||||
textAlignment = .center
|
||||
font = UIFont.systemFont(ofSize: 13)
|
||||
textColor = UIColor.white
|
||||
font = .systemFont(ofSize: 13)
|
||||
textColor = .white
|
||||
}
|
||||
|
||||
// PRAGMA: helpers
|
||||
|
||||
open func addBadgeOnView(_ onView:UIView) {
|
||||
|
||||
// PRAGMA: public
|
||||
|
||||
open func addBadgeOnView(_ onView: UIView) {
|
||||
|
||||
onView.addSubview(self)
|
||||
|
||||
// create constraints
|
||||
topConstraint = NSLayoutConstraint(item: self,
|
||||
attribute: NSLayoutAttribute.top,
|
||||
relatedBy: NSLayoutRelation.equal,
|
||||
toItem: onView,
|
||||
attribute: NSLayoutAttribute.top,
|
||||
multiplier: 1,
|
||||
constant: 3)
|
||||
onView.addConstraint(topConstraint!)
|
||||
|
||||
centerXConstraint = NSLayoutConstraint(item: self,
|
||||
attribute: NSLayoutAttribute.centerX,
|
||||
relatedBy: NSLayoutRelation.equal,
|
||||
toItem: onView,
|
||||
attribute: NSLayoutAttribute.centerX,
|
||||
multiplier: 1,
|
||||
constant: 10)
|
||||
onView.addConstraint(centerXConstraint!)
|
||||
let top = NSLayoutConstraint(item: self,
|
||||
attribute: .top,
|
||||
relatedBy: .equal,
|
||||
toItem: onView,
|
||||
attribute: .top,
|
||||
multiplier: 1,
|
||||
constant: 3)
|
||||
onView.addConstraint(top)
|
||||
topConstraint = top
|
||||
|
||||
let centerX = NSLayoutConstraint(item: self,
|
||||
attribute: .centerX,
|
||||
relatedBy: .equal,
|
||||
toItem: onView,
|
||||
attribute: .centerX,
|
||||
multiplier: 1,
|
||||
constant: 10)
|
||||
onView.addConstraint(centerX)
|
||||
centerXConstraint = centerX
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,74 +20,81 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
public protocol RAMItemAnimationProtocol {
|
||||
|
||||
func playAnimation(_ icon : UIImageView, textLabel : UILabel)
|
||||
func deselectAnimation(_ icon : UIImageView, textLabel : UILabel, defaultTextColor : UIColor, defaultIconColor : UIColor)
|
||||
func selectedState(_ icon : UIImageView, textLabel : UILabel)
|
||||
|
||||
func playAnimation(_ icon: UIImageView, textLabel: UILabel)
|
||||
func deselectAnimation(_ icon: UIImageView, textLabel: UILabel, defaultTextColor: UIColor, defaultIconColor: UIColor)
|
||||
func selectedState(_ icon: UIImageView, textLabel: UILabel)
|
||||
}
|
||||
|
||||
/// Base class for UITabBarItems animation
|
||||
open class RAMItemAnimation: NSObject, RAMItemAnimationProtocol {
|
||||
|
||||
// MARK: constants
|
||||
|
||||
struct Constants {
|
||||
|
||||
struct AnimationKeys {
|
||||
|
||||
static let Scale = "transform.scale"
|
||||
static let Rotation = "transform.rotation"
|
||||
static let KeyFrame = "contents"
|
||||
static let PositionY = "position.y"
|
||||
static let Opacity = "opacity"
|
||||
|
||||
// MARK: constants
|
||||
|
||||
struct Constants {
|
||||
|
||||
struct AnimationKeys {
|
||||
|
||||
static let scale = "transform.scale"
|
||||
static let rotation = "transform.rotation"
|
||||
static let keyFrame = "contents"
|
||||
static let positionY = "position.y"
|
||||
static let opacity = "opacity"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: properties
|
||||
|
||||
/// The duration of the animation
|
||||
@IBInspectable open var duration : CGFloat = 0.5
|
||||
|
||||
/// The text color in selected state.
|
||||
@IBInspectable open var textSelectedColor: UIColor = UIColor.init(red: 0, green: 0.478431, blue: 1, alpha: 1)
|
||||
|
||||
/// The icon color in selected state.
|
||||
@IBInspectable open var iconSelectedColor: UIColor!
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is selected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open func playAnimation(_ icon : UIImageView, textLabel : UILabel) {
|
||||
fatalError("override method in subclass")
|
||||
}
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is unselected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
- parameter defaultTextColor: default UITabBarItem text color
|
||||
- parameter defaultIconColor: default UITabBarItem icon color
|
||||
*/
|
||||
open func deselectAnimation(_ icon : UIImageView, textLabel : UILabel, defaultTextColor : UIColor, defaultIconColor : UIColor) {
|
||||
fatalError("override method in subclass")
|
||||
}
|
||||
|
||||
/**
|
||||
Method call when TabBarController did load
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open func selectedState(_ icon: UIImageView, textLabel : UILabel) {
|
||||
fatalError("override method in subclass")
|
||||
}
|
||||
|
||||
// MARK: properties
|
||||
|
||||
/// The duration of the animation
|
||||
@IBInspectable open var duration: CGFloat = 0.5
|
||||
|
||||
/// The text color in selected state.
|
||||
@IBInspectable open var textSelectedColor: UIColor = UIColor(red: 0, green: 0.478431, blue: 1, alpha: 1)
|
||||
|
||||
/// The icon color in selected state.
|
||||
@IBInspectable open var iconSelectedColor: UIColor!
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is selected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open func playAnimation(_: UIImageView, textLabel _: UILabel) {
|
||||
fatalError("override method in subclass")
|
||||
}
|
||||
|
||||
/**
|
||||
Start animation, method call when UITabBarItem is unselected
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
- parameter defaultTextColor: default UITabBarItem text color
|
||||
- parameter defaultIconColor: default UITabBarItem icon color
|
||||
*/
|
||||
open func deselectAnimation(_: UIImageView, textLabel _: UILabel, defaultTextColor _: UIColor, defaultIconColor _: UIColor) {
|
||||
fatalError("override method in subclass")
|
||||
}
|
||||
|
||||
/**
|
||||
Method call when TabBarController did load
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open func selectedState(_: UIImageView, textLabel _: UILabel) {
|
||||
fatalError("override method in subclass")
|
||||
}
|
||||
|
||||
/**
|
||||
(Optional) Method call when TabBarController did load
|
||||
|
||||
- parameter icon: animating UITabBarItem icon
|
||||
- parameter textLabel: animating UITabBarItem textLabel
|
||||
*/
|
||||
open func deselectedState(_: UIImageView, textLabel _: UILabel) {}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// Collection+Extensions.swift
|
||||
//
|
||||
// Copyright (c) 11/10/14 Ramotion Inc. (http://ramotion.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Collection where Self.Index == Self.Indices.Iterator.Element {
|
||||
/**
|
||||
Returns an optional element. If the `index` does not exist in the collection, the subscript returns nil.
|
||||
|
||||
- parameter safe: The index of the element to return, if it exists.
|
||||
|
||||
- returns: An optional element from the collection at the specified index.
|
||||
*/
|
||||
public subscript(safe i: Index) -> Self.Iterator.Element? {
|
||||
return at(i)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns an optional element. If the `index` does not exist in the collection, the function returns nil.
|
||||
|
||||
- parameter index: The index of the element to return, if it exists.
|
||||
|
||||
- returns: An optional element from the collection at the specified index.
|
||||
*/
|
||||
public func at(_ i: Index) -> Self.Iterator.Element? {
|
||||
return indices.contains(i) ? self[i] : nil
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
//
|
||||
// AnimatedTabBar.h
|
||||
// AnimatedTabBar
|
||||
//
|
||||
// Created by Alex K. on 02/06/16.
|
||||
// Copyright © 2016 Ramotion. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
//! Project version number for AnimatedTabBar.
|
||||
FOUNDATION_EXPORT double AnimatedTabBarVersionNumber;
|
||||
|
||||
//! Project version string for AnimatedTabBar.
|
||||
FOUNDATION_EXPORT const unsigned char AnimatedTabBarVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <AnimatedTabBar/PublicHeader.h>
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,116 @@
|
||||
//
|
||||
// AnimatedTabBarTests.swift
|
||||
// AnimatedTabBarTests
|
||||
//
|
||||
// Created by Alex K on 17/08/2018.
|
||||
// Copyright © 2018 Ramotion. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import Animated_Tab_Bar
|
||||
|
||||
class AnimatedTabBarTests: XCTestCase {
|
||||
|
||||
var tabBarController: RAMAnimatedTabBarController!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
let storyboard = UIStoryboard(name: "Main", bundle: nil)
|
||||
tabBarController = storyboard.instantiateViewController(withIdentifier: "RAMAnimatedTabBarController") as? RAMAnimatedTabBarController
|
||||
_ = tabBarController.view
|
||||
|
||||
}
|
||||
override func tearDown() {
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
func testCreateController() {
|
||||
XCTAssertNotNil(tabBarController)
|
||||
}
|
||||
|
||||
func testIsBottomLineShowen() {
|
||||
|
||||
XCTAssertEqual(tabBarController.bottomLine, nil)
|
||||
|
||||
tabBarController.isBottomLineShow = true
|
||||
XCTAssertNotNil(tabBarController.bottomLine)
|
||||
|
||||
tabBarController.isBottomLineShow = false
|
||||
XCTAssertEqual(tabBarController.bottomLine, nil)
|
||||
}
|
||||
|
||||
func testChangeSelectedColor() {
|
||||
let selectedColor = UIColor.red
|
||||
let iconSelectedColor = UIColor.green
|
||||
tabBarController.changeSelectedColor(selectedColor, iconSelectedColor: iconSelectedColor)
|
||||
|
||||
tabBarController.animatedItems.forEach {
|
||||
XCTAssertEqual($0.animation.textSelectedColor, selectedColor)
|
||||
XCTAssertEqual($0.animation.iconSelectedColor, iconSelectedColor)
|
||||
}
|
||||
}
|
||||
|
||||
func testAnimationBarHidden() {
|
||||
|
||||
XCTAssertEqual(tabBarController.tabBar.isHidden, false)
|
||||
tabBarController.animatedItems.forEach {
|
||||
XCTAssertEqual($0.iconView?.icon.superview?.isHidden, false)
|
||||
}
|
||||
|
||||
tabBarController.animationTabBarHidden(true)
|
||||
|
||||
XCTAssertEqual(tabBarController.tabBar.isHidden, true)
|
||||
tabBarController.animatedItems.forEach {
|
||||
XCTAssertEqual($0.iconView?.icon.superview?.isHidden, true)
|
||||
}
|
||||
}
|
||||
|
||||
func testSelectIndex() {
|
||||
let toIndex = 2
|
||||
tabBarController.setSelectIndex(from: 0, to: toIndex)
|
||||
XCTAssertEqual(tabBarController.selectedIndex, toIndex)
|
||||
}
|
||||
|
||||
func testAnimatedItems() {
|
||||
XCTAssertEqual(tabBarController.viewControllers?.count, tabBarController.animatedItems.count)
|
||||
}
|
||||
|
||||
func testIsBottomLineShow() {
|
||||
XCTAssertEqual(tabBarController.isBottomLineShow, false)
|
||||
XCTAssertNil(tabBarController.bottomLine)
|
||||
tabBarController.isBottomLineShow = true
|
||||
|
||||
XCTAssertEqual(tabBarController.isBottomLineShow, true)
|
||||
XCTAssertNotNil(tabBarController.bottomLine)
|
||||
}
|
||||
|
||||
func testBottomLineColor() {
|
||||
let color = UIColor.red
|
||||
tabBarController.isBottomLineShow = true
|
||||
XCTAssertNotEqual(tabBarController.bottomLine, color)
|
||||
tabBarController.bottomLineColor = color
|
||||
XCTAssertEqual(tabBarController.bottomLineColor, color)
|
||||
}
|
||||
|
||||
func testContainersCount() {
|
||||
XCTAssertEqual(tabBarController.viewControllers?.count, tabBarController.containers.count)
|
||||
}
|
||||
|
||||
func testBadge() {
|
||||
let value = "1"
|
||||
tabBarController.animatedItems.first?.badgeValue = value
|
||||
XCTAssertEqual(tabBarController.animatedItems.first?.badgeValue, tabBarController.animatedItems.first?.badge?.text)
|
||||
}
|
||||
|
||||
func testIsEnabled() {
|
||||
guard let item = tabBarController.animatedItems.first else { return }
|
||||
item.isEnabled = true
|
||||
XCTAssertEqual(item.iconView?.icon.alpha, 1)
|
||||
XCTAssertEqual(item.iconView?.textLabel.alpha, 1)
|
||||
|
||||
item.isEnabled = false
|
||||
XCTAssertEqual(item.iconView?.icon.alpha, 0.5)
|
||||
XCTAssertEqual(item.iconView?.textLabel.alpha, 0.5)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
@@ -16,8 +16,6 @@
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
@@ -0,0 +1,24 @@
|
||||
import XCTest
|
||||
@testable import Animated_Tab_Bar
|
||||
|
||||
class RAMBadgeTests: XCTestCase {
|
||||
|
||||
var badge: RAMBadge!
|
||||
|
||||
override func setUp() {
|
||||
badge = RAMBadge.badge()
|
||||
}
|
||||
|
||||
func testCreateBadge() {
|
||||
XCTAssertNotNil(badge)
|
||||
}
|
||||
|
||||
func testAddBadgeOnView() {
|
||||
let view = UIView()
|
||||
XCTAssertNil(badge.superview)
|
||||
badge.addBadgeOnView(view)
|
||||
XCTAssertNotNil(badge.superview)
|
||||
XCTAssertNotNil(badge.topConstraint)
|
||||
XCTAssertNotNil(badge.centerXConstraint)
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,14 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
3950EDD82354950E0072BAAD /* RAMAnimatedTabBarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3950EDD72354950E0072BAAD /* RAMAnimatedTabBarItem.swift */; };
|
||||
3950EDD9235496AF0072BAAD /* RAMAnimatedTabBarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3950EDD72354950E0072BAAD /* RAMAnimatedTabBarItem.swift */; };
|
||||
3950EDDC235497650072BAAD /* Collection+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3950EDDB235497650072BAAD /* Collection+Extensions.swift */; };
|
||||
3950EDDD235497910072BAAD /* Collection+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3950EDDB235497650072BAAD /* Collection+Extensions.swift */; };
|
||||
5A1F33BC2126AA3D004B8735 /* AnimatedTabBarTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A1F33BB2126AA3D004B8735 /* AnimatedTabBarTests.swift */; };
|
||||
5A5D3FF021B91D0700304986 /* RAMBadgeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A5D3FEF21B91D0700304986 /* RAMBadgeTests.swift */; };
|
||||
5ADAB94A209B0FA8006CCD85 /* RAMAnimatedTabBarController+BottomLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ADAB949209B0FA8006CCD85 /* RAMAnimatedTabBarController+BottomLine.swift */; };
|
||||
5ADAB94B209B51E5006CCD85 /* RAMAnimatedTabBarController+BottomLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ADAB949209B0FA8006CCD85 /* RAMAnimatedTabBarController+BottomLine.swift */; };
|
||||
849507011D05772B0005EC1A /* ToolsAnimation.plist in Resources */ = {isa = PBXBuildFile; fileRef = 849507001D05772B0005EC1A /* ToolsAnimation.plist */; };
|
||||
84BC64221C22E4C800B89B79 /* RAMBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84BC64211C22E4C800B89B79 /* RAMBadge.swift */; };
|
||||
84D4B7A11DB0D35500EE38C6 /* TabBarLib.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D4B79F1DB0D35500EE38C6 /* TabBarLib.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@@ -25,7 +33,6 @@
|
||||
CE41467D1A1B923D0037F03C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE41467B1A1B923D0037F03C /* Main.storyboard */; };
|
||||
CE41467F1A1B923D0037F03C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CE41467E1A1B923D0037F03C /* Images.xcassets */; };
|
||||
CE4146821A1B923D0037F03C /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4146801A1B923D0037F03C /* LaunchScreen.xib */; };
|
||||
CE41468E1A1B923D0037F03C /* RAMAnimatedTabBarDemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE41468D1A1B923D0037F03C /* RAMAnimatedTabBarDemoTests.swift */; };
|
||||
CE41469E1A1B944D0037F03C /* RAMFrameItemAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE41469A1A1B944D0037F03C /* RAMFrameItemAnimation.swift */; };
|
||||
CE41469F1A1B944D0037F03C /* RAMTransitionItemAnimations.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE41469C1A1B944D0037F03C /* RAMTransitionItemAnimations.swift */; };
|
||||
CE4146A01A1B944D0037F03C /* RAMItemAnimationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE41469D1A1B944D0037F03C /* RAMItemAnimationProtocol.swift */; };
|
||||
@@ -36,6 +43,13 @@
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
5A1F33BE2126AA3D004B8735 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = CE41466A1A1B923D0037F03C /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = CE4146711A1B923D0037F03C;
|
||||
remoteInfo = RAMAnimatedTabBarDemo;
|
||||
};
|
||||
84D4B7A21DB0D35500EE38C6 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = CE41466A1A1B923D0037F03C /* Project object */;
|
||||
@@ -43,13 +57,6 @@
|
||||
remoteGlobalIDString = 84D4B79C1DB0D35500EE38C6;
|
||||
remoteInfo = TabBarLib;
|
||||
};
|
||||
CE4146881A1B923D0037F03C /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = CE41466A1A1B923D0037F03C /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = CE4146711A1B923D0037F03C;
|
||||
remoteInfo = RAMAnimatedTabBarDemo;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@@ -67,23 +74,25 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
3950EDD72354950E0072BAAD /* RAMAnimatedTabBarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RAMAnimatedTabBarItem.swift; sourceTree = "<group>"; };
|
||||
3950EDDB235497650072BAAD /* Collection+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+Extensions.swift"; sourceTree = "<group>"; };
|
||||
5A1F33B92126AA3D004B8735 /* AnimatedTabBarTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AnimatedTabBarTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
5A1F33BB2126AA3D004B8735 /* AnimatedTabBarTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedTabBarTests.swift; sourceTree = "<group>"; };
|
||||
5A1F33BD2126AA3D004B8735 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
5A5D3FEF21B91D0700304986 /* RAMBadgeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RAMBadgeTests.swift; sourceTree = "<group>"; };
|
||||
5ADAB949209B0FA8006CCD85 /* RAMAnimatedTabBarController+BottomLine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RAMAnimatedTabBarController+BottomLine.swift"; sourceTree = "<group>"; };
|
||||
849507001D05772B0005EC1A /* ToolsAnimation.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ToolsAnimation.plist; sourceTree = "<group>"; };
|
||||
8499D8EF1D0069C6004B5B37 /* AnimatedTabBar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnimatedTabBar.h; sourceTree = "<group>"; };
|
||||
8499D8F11D0069C6004B5B37 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
84BC64211C22E4C800B89B79 /* RAMBadge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RAMBadge.swift; sourceTree = "<group>"; };
|
||||
84D4B79D1DB0D35500EE38C6 /* RAMAnimatedTabBarController.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RAMAnimatedTabBarController.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
84D4B79F1DB0D35500EE38C6 /* TabBarLib.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TabBarLib.h; sourceTree = "<group>"; };
|
||||
84D4B7A01DB0D35500EE38C6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
CE4146721A1B923D0037F03C /* RAMAnimatedTabBarDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RAMAnimatedTabBarDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
CE4146721A1B923D0037F03C /* Animated Tab Bar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Animated Tab Bar.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
CE4146761A1B923D0037F03C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
CE4146771A1B923D0037F03C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
CE4146791A1B923D0037F03C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||
CE41467C1A1B923D0037F03C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
CE41467E1A1B923D0037F03C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
CE4146811A1B923D0037F03C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
CE4146871A1B923D0037F03C /* RAMAnimatedTabBarDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RAMAnimatedTabBarDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
CE41468C1A1B923D0037F03C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
CE41468D1A1B923D0037F03C /* RAMAnimatedTabBarDemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RAMAnimatedTabBarDemoTests.swift; sourceTree = "<group>"; };
|
||||
CE41469A1A1B944D0037F03C /* RAMFrameItemAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RAMFrameItemAnimation.swift; sourceTree = "<group>"; };
|
||||
CE41469C1A1B944D0037F03C /* RAMTransitionItemAnimations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RAMTransitionItemAnimations.swift; sourceTree = "<group>"; };
|
||||
CE41469D1A1B944D0037F03C /* RAMItemAnimationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RAMItemAnimationProtocol.swift; sourceTree = "<group>"; };
|
||||
@@ -94,6 +103,13 @@
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
5A1F33B62126AA3D004B8735 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
84D4B7991DB0D35500EE38C6 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -109,23 +125,33 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CE4146841A1B923D0037F03C /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
8499D8EE1D0069C6004B5B37 /* AnimatedTabBar */ = {
|
||||
3950EDDA2354974D0072BAAD /* Utilities */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8499D8EF1D0069C6004B5B37 /* AnimatedTabBar.h */,
|
||||
8499D8F11D0069C6004B5B37 /* Info.plist */,
|
||||
3950EDDB235497650072BAAD /* Collection+Extensions.swift */,
|
||||
);
|
||||
path = AnimatedTabBar;
|
||||
path = Utilities;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5A1F33BA2126AA3D004B8735 /* AnimatedTabBarTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5A1F33BB2126AA3D004B8735 /* AnimatedTabBarTests.swift */,
|
||||
5A1F33BD2126AA3D004B8735 /* Info.plist */,
|
||||
5A5D3FEF21B91D0700304986 /* RAMBadgeTests.swift */,
|
||||
);
|
||||
path = AnimatedTabBarTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5AC42AE5210AFA110009889F /* BottomLine */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5ADAB949209B0FA8006CCD85 /* RAMAnimatedTabBarController+BottomLine.swift */,
|
||||
);
|
||||
path = BottomLine;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
84BC64201C22E41F00B89B79 /* RAMBadge */ = {
|
||||
@@ -149,9 +175,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CE4146741A1B923D0037F03C /* RAMAnimatedTabBarDemo */,
|
||||
CE41468A1A1B923D0037F03C /* RAMAnimatedTabBarDemoTests */,
|
||||
8499D8EE1D0069C6004B5B37 /* AnimatedTabBar */,
|
||||
84D4B79E1DB0D35500EE38C6 /* TabBarLib */,
|
||||
5A1F33BA2126AA3D004B8735 /* AnimatedTabBarTests */,
|
||||
CE4146731A1B923D0037F03C /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
@@ -159,9 +184,9 @@
|
||||
CE4146731A1B923D0037F03C /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CE4146721A1B923D0037F03C /* RAMAnimatedTabBarDemo.app */,
|
||||
CE4146871A1B923D0037F03C /* RAMAnimatedTabBarDemoTests.xctest */,
|
||||
CE4146721A1B923D0037F03C /* Animated Tab Bar.app */,
|
||||
84D4B79D1DB0D35500EE38C6 /* RAMAnimatedTabBarController.framework */,
|
||||
5A1F33B92126AA3D004B8735 /* AnimatedTabBarTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -189,28 +214,14 @@
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CE41468A1A1B923D0037F03C /* RAMAnimatedTabBarDemoTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CE41468D1A1B923D0037F03C /* RAMAnimatedTabBarDemoTests.swift */,
|
||||
CE41468B1A1B923D0037F03C /* Supporting Files */,
|
||||
);
|
||||
path = RAMAnimatedTabBarDemoTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CE41468B1A1B923D0037F03C /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CE41468C1A1B923D0037F03C /* Info.plist */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CE4146971A1B94170037F03C /* RAMAnimatedTabBarControlller */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3950EDDA2354974D0072BAAD /* Utilities */,
|
||||
5AC42AE5210AFA110009889F /* BottomLine */,
|
||||
84BC64201C22E41F00B89B79 /* RAMBadge */,
|
||||
CE90A83F1A1C7C14002D8931 /* RAMAnimatedTabBarController.swift */,
|
||||
3950EDD72354950E0072BAAD /* RAMAnimatedTabBarItem.swift */,
|
||||
CE4146981A1B944D0037F03C /* Animations */,
|
||||
CE41469D1A1B944D0037F03C /* RAMItemAnimationProtocol.swift */,
|
||||
);
|
||||
@@ -292,6 +303,24 @@
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
5A1F33B82126AA3D004B8735 /* AnimatedTabBarTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 5A1F33C22126AA3D004B8735 /* Build configuration list for PBXNativeTarget "AnimatedTabBarTests" */;
|
||||
buildPhases = (
|
||||
5A1F33B52126AA3D004B8735 /* Sources */,
|
||||
5A1F33B62126AA3D004B8735 /* Frameworks */,
|
||||
5A1F33B72126AA3D004B8735 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
5A1F33BF2126AA3D004B8735 /* PBXTargetDependency */,
|
||||
);
|
||||
name = AnimatedTabBarTests;
|
||||
productName = AnimatedTabBarTests;
|
||||
productReference = 5A1F33B92126AA3D004B8735 /* AnimatedTabBarTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
84D4B79C1DB0D35500EE38C6 /* RAMAnimatedTabBarController */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 84D4B7A81DB0D35500EE38C6 /* Build configuration list for PBXNativeTarget "RAMAnimatedTabBarController" */;
|
||||
@@ -317,7 +346,6 @@
|
||||
CE41466E1A1B923D0037F03C /* Sources */,
|
||||
CE41466F1A1B923D0037F03C /* Frameworks */,
|
||||
CE4146701A1B923D0037F03C /* Resources */,
|
||||
847D23E81C63319B0085E882 /* SwiftLint */,
|
||||
8499D8F91D0069C6004B5B37 /* Embed Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
@@ -327,55 +355,39 @@
|
||||
);
|
||||
name = RAMAnimatedTabBarDemo;
|
||||
productName = RAMAnimatedTabBarDemo;
|
||||
productReference = CE4146721A1B923D0037F03C /* RAMAnimatedTabBarDemo.app */;
|
||||
productReference = CE4146721A1B923D0037F03C /* Animated Tab Bar.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
CE4146861A1B923D0037F03C /* RAMAnimatedTabBarDemoTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = CE4146941A1B923D0037F03C /* Build configuration list for PBXNativeTarget "RAMAnimatedTabBarDemoTests" */;
|
||||
buildPhases = (
|
||||
CE4146831A1B923D0037F03C /* Sources */,
|
||||
CE4146841A1B923D0037F03C /* Frameworks */,
|
||||
CE4146851A1B923D0037F03C /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
CE4146891A1B923D0037F03C /* PBXTargetDependency */,
|
||||
);
|
||||
name = RAMAnimatedTabBarDemoTests;
|
||||
productName = RAMAnimatedTabBarDemoTests;
|
||||
productReference = CE4146871A1B923D0037F03C /* RAMAnimatedTabBarDemoTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
CE41466A1A1B923D0037F03C /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0700;
|
||||
LastUpgradeCheck = 0830;
|
||||
LastSwiftUpdateCheck = 0940;
|
||||
LastUpgradeCheck = 1020;
|
||||
ORGANIZATIONNAME = Ramotion;
|
||||
TargetAttributes = {
|
||||
5A1F33B82126AA3D004B8735 = {
|
||||
CreatedOnToolsVersion = 9.4;
|
||||
LastSwiftMigration = 1020;
|
||||
ProvisioningStyle = Automatic;
|
||||
TestTargetID = CE4146711A1B923D0037F03C;
|
||||
};
|
||||
84D4B79C1DB0D35500EE38C6 = {
|
||||
CreatedOnToolsVersion = 8.0;
|
||||
LastSwiftMigration = 0800;
|
||||
LastSwiftMigration = 1020;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
CE4146711A1B923D0037F03C = {
|
||||
CreatedOnToolsVersion = 6.1;
|
||||
LastSwiftMigration = 0800;
|
||||
};
|
||||
CE4146861A1B923D0037F03C = {
|
||||
CreatedOnToolsVersion = 6.1;
|
||||
TestTargetID = CE4146711A1B923D0037F03C;
|
||||
LastSwiftMigration = 1020;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = CE41466D1A1B923D0037F03C /* Build configuration list for PBXProject "RAMAnimatedTabBarDemo" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
@@ -387,13 +399,20 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
CE4146711A1B923D0037F03C /* RAMAnimatedTabBarDemo */,
|
||||
CE4146861A1B923D0037F03C /* RAMAnimatedTabBarDemoTests */,
|
||||
84D4B79C1DB0D35500EE38C6 /* RAMAnimatedTabBarController */,
|
||||
5A1F33B82126AA3D004B8735 /* AnimatedTabBarTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
5A1F33B72126AA3D004B8735 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
84D4B79B1DB0D35500EE38C6 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -412,40 +431,28 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CE4146851A1B923D0037F03C /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
847D23E81C63319B0085E882 /* SwiftLint */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
5A1F33B52126AA3D004B8735 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = SwiftLint;
|
||||
outputPaths = (
|
||||
5A5D3FF021B91D0700304986 /* RAMBadgeTests.swift in Sources */,
|
||||
5A1F33BC2126AA3D004B8735 /* AnimatedTabBarTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"SwiftLint does not exist, download from https://github.com/realm/SwiftLint\"\nfi";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
84D4B7981DB0D35500EE38C6 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
84D4B7A91DB0D37700EE38C6 /* RAMBadge.swift in Sources */,
|
||||
84D4B7AF1DB0D38B00EE38C6 /* RAMTransitionItemAnimations.swift in Sources */,
|
||||
5ADAB94B209B51E5006CCD85 /* RAMAnimatedTabBarController+BottomLine.swift in Sources */,
|
||||
3950EDDD235497910072BAAD /* Collection+Extensions.swift in Sources */,
|
||||
84D4B7B01DB0D38F00EE38C6 /* RAMItemAnimationProtocol.swift in Sources */,
|
||||
3950EDD9235496AF0072BAAD /* RAMAnimatedTabBarItem.swift in Sources */,
|
||||
84D4B7AB1DB0D37F00EE38C6 /* RAMFumeAnimation.swift in Sources */,
|
||||
84D4B7AA1DB0D37B00EE38C6 /* RAMAnimatedTabBarController.swift in Sources */,
|
||||
84D4B7AC1DB0D38100EE38C6 /* RAMBounceAnimation.swift in Sources */,
|
||||
@@ -461,37 +468,32 @@
|
||||
CE41469E1A1B944D0037F03C /* RAMFrameItemAnimation.swift in Sources */,
|
||||
CE90A8401A1C7C14002D8931 /* RAMAnimatedTabBarController.swift in Sources */,
|
||||
CE41467A1A1B923D0037F03C /* ViewController.swift in Sources */,
|
||||
5ADAB94A209B0FA8006CCD85 /* RAMAnimatedTabBarController+BottomLine.swift in Sources */,
|
||||
CE90A8431A1C8DD3002D8931 /* RAMRotationAnimation.swift in Sources */,
|
||||
F3E056BE1A2DD57600F33DDA /* RAMFumeAnimation.swift in Sources */,
|
||||
CE41469F1A1B944D0037F03C /* RAMTransitionItemAnimations.swift in Sources */,
|
||||
3950EDDC235497650072BAAD /* Collection+Extensions.swift in Sources */,
|
||||
84BC64221C22E4C800B89B79 /* RAMBadge.swift in Sources */,
|
||||
3950EDD82354950E0072BAAD /* RAMAnimatedTabBarItem.swift in Sources */,
|
||||
CE4146A01A1B944D0037F03C /* RAMItemAnimationProtocol.swift in Sources */,
|
||||
CE4146781A1B923D0037F03C /* AppDelegate.swift in Sources */,
|
||||
CE90A8791A1CE200002D8931 /* RAMBounceAnimation.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CE4146831A1B923D0037F03C /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CE41468E1A1B923D0037F03C /* RAMAnimatedTabBarDemoTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
5A1F33BF2126AA3D004B8735 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = CE4146711A1B923D0037F03C /* RAMAnimatedTabBarDemo */;
|
||||
targetProxy = 5A1F33BE2126AA3D004B8735 /* PBXContainerItemProxy */;
|
||||
};
|
||||
84D4B7A31DB0D35500EE38C6 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 84D4B79C1DB0D35500EE38C6 /* RAMAnimatedTabBarController */;
|
||||
targetProxy = 84D4B7A21DB0D35500EE38C6 /* PBXContainerItemProxy */;
|
||||
};
|
||||
CE4146891A1B923D0037F03C /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = CE4146711A1B923D0037F03C /* RAMAnimatedTabBarDemo */;
|
||||
targetProxy = CE4146881A1B923D0037F03C /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
@@ -514,13 +516,63 @@
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
5A1F33C02126AA3D004B8735 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = AnimatedTabBarTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.AnimatedTabBarTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Animated Tab Bar.app/Animated Tab Bar";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
5A1F33C12126AA3D004B8735 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = AnimatedTabBarTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.AnimatedTabBarTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Animated Tab Bar.app/Animated Tab Bar";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
84D4B7A61DB0D35500EE38C6 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
@@ -537,7 +589,7 @@
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
@@ -549,7 +601,7 @@
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
@@ -566,7 +618,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.RAMAnimatedTabBarController;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
@@ -576,18 +628,27 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
@@ -610,12 +671,12 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.2;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
@@ -624,18 +685,27 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
@@ -651,11 +721,11 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.2;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
@@ -674,9 +744,9 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.dev;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PRODUCT_NAME = "Animated Tab Bar";
|
||||
PROVISIONING_PROFILE = "";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -693,47 +763,24 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.dev;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PRODUCT_NAME = "Animated Tab Bar";
|
||||
PROVISIONING_PROFILE = "";
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
CE4146951A1B923D0037F03C /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = RAMAnimatedTabBarDemoTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.Ramotion.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 3.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RAMAnimatedTabBarDemo.app/RAMAnimatedTabBarDemo";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
CE4146961A1B923D0037F03C /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
|
||||
INFOPLIST_FILE = RAMAnimatedTabBarDemoTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.Ramotion.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 3.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RAMAnimatedTabBarDemo.app/RAMAnimatedTabBarDemo";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
5A1F33C22126AA3D004B8735 /* Build configuration list for PBXNativeTarget "AnimatedTabBarTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
5A1F33C02126AA3D004B8735 /* Debug */,
|
||||
5A1F33C12126AA3D004B8735 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
84D4B7A81DB0D35500EE38C6 /* Build configuration list for PBXNativeTarget "RAMAnimatedTabBarController" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
@@ -761,15 +808,6 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
CE4146941A1B923D0037F03C /* Build configuration list for PBXNativeTarget "RAMAnimatedTabBarDemoTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
CE4146951A1B923D0037F03C /* Debug */,
|
||||
CE4146961A1B923D0037F03C /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = CE41466A1A1B923D0037F03C /* Project object */;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0830"
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -28,7 +28,26 @@
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "5A1F33B82126AA3D004B8735"
|
||||
BuildableName = "AnimatedTabBarTests.xctest"
|
||||
BlueprintName = "AnimatedTabBarTests"
|
||||
ReferencedContainer = "container:RAMAnimatedTabBarDemo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "84D4B79C1DB0D35500EE38C6"
|
||||
BuildableName = "RAMAnimatedTabBarController.framework"
|
||||
BlueprintName = "RAMAnimatedTabBarController"
|
||||
ReferencedContainer = "container:RAMAnimatedTabBarDemo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
|
||||
@@ -13,26 +13,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
|
||||
private func application(
|
||||
application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
|
||||
|
||||
public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func applicationWillResignActive(_ application: UIApplication) {
|
||||
}
|
||||
|
||||
func applicationDidEnterBackground(_ application: UIApplication) {
|
||||
}
|
||||
|
||||
func applicationWillEnterForeground(_ application: UIApplication) {
|
||||
}
|
||||
|
||||
func applicationDidBecomeActive(_ application: UIApplication) {
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_ application: UIApplication) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
@@ -17,21 +21,20 @@
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="RAMAnimatedTabBarDemo" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Animated Tab Bar" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||
<rect key="frame" x="93.5" y="218.5" width="294" height="43"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
||||
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="SHs-oA-M0R"/>
|
||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="15G1004" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="QjJ-1j-Kct">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15400" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="QjJ-1j-Kct">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15404"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
@@ -10,19 +12,12 @@
|
||||
<scene sceneID="Y99-CA-jqU">
|
||||
<objects>
|
||||
<viewController id="wJE-Q4-t8C" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="n1y-U7-ZG1"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="ccN-XV-rhh"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="PmG-Vl-9D1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="FumeAnimation" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UxN-OP-GHb">
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="348" id="7vr-pR-SXo"/>
|
||||
<constraint firstAttribute="height" constant="71" id="mCo-IA-Ilv"/>
|
||||
</constraints>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Fume Animation" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UxN-OP-GHb">
|
||||
<rect key="frame" x="93" y="317.5" width="189" height="32.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="27"/>
|
||||
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -30,23 +25,19 @@
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="centerX" secondItem="UxN-OP-GHb" secondAttribute="centerX" id="1l9-FQ-w0o"/>
|
||||
<constraint firstAttribute="centerY" secondItem="UxN-OP-GHb" secondAttribute="centerY" constant="115.5" id="5ae-83-gzq"/>
|
||||
<constraint firstItem="cbk-oV-z7H" firstAttribute="centerX" secondItem="UxN-OP-GHb" secondAttribute="centerX" id="1l9-FQ-w0o"/>
|
||||
<constraint firstAttribute="centerY" secondItem="UxN-OP-GHb" secondAttribute="centerY" id="5ae-83-gzq"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="cbk-oV-z7H"/>
|
||||
</view>
|
||||
<tabBarItem key="tabBarItem" title="Item" image="drop" id="tS2-0E-St8" customClass="RAMAnimatedTabBarItem" customModule="RAMAnimatedTabBarDemo" customModuleProvider="target">
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="textColor">
|
||||
<color key="value" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<tabBarItem key="tabBarItem" title="Item" image="drop" id="tS2-0E-St8" customClass="RAMAnimatedTabBarItem" customModule="Animated_Tab_Bar" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="animation" destination="Lky-Hp-l9U" id="r67-ap-cxK"/>
|
||||
</connections>
|
||||
</tabBarItem>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="zW4-Q6-RN5" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
<customObject id="Lky-Hp-l9U" customClass="RAMFumeAnimation" customModule="RAMAnimatedTabBarDemo" customModuleProvider="target">
|
||||
<customObject id="Lky-Hp-l9U" customClass="RAMFumeAnimation" customModule="Animated_Tab_Bar" customModuleProvider="target">
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="duration">
|
||||
<real key="value" value="0.40000000000000002"/>
|
||||
@@ -59,20 +50,13 @@
|
||||
<!--Item1-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="RAMAnimatedTabBarDemo" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="Animated_Tab_Bar" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="TransitionItemAnimation" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AeA-ED-4jL">
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="71" id="51d-lD-JHB"/>
|
||||
<constraint firstAttribute="width" constant="348" id="6Ur-Ph-cXK"/>
|
||||
</constraints>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Transition Animation" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AeA-ED-4jL">
|
||||
<rect key="frame" x="69.5" y="317.5" width="236" height="32.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="27"/>
|
||||
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -80,23 +64,19 @@
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="centerY" secondItem="AeA-ED-4jL" secondAttribute="centerY" constant="114.5" id="Ifi-6x-Ruv"/>
|
||||
<constraint firstAttribute="centerX" secondItem="AeA-ED-4jL" secondAttribute="centerX" id="gXX-8c-cGG"/>
|
||||
<constraint firstAttribute="centerY" secondItem="AeA-ED-4jL" secondAttribute="centerY" id="Ifi-6x-Ruv"/>
|
||||
<constraint firstItem="8ec-QI-6Cw" firstAttribute="centerX" secondItem="AeA-ED-4jL" secondAttribute="centerX" id="gXX-8c-cGG"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="8ec-QI-6Cw"/>
|
||||
</view>
|
||||
<tabBarItem key="tabBarItem" title="Item1" image="icon_pin" id="lUH-JS-dWf" customClass="RAMAnimatedTabBarItem" customModule="RAMAnimatedTabBarDemo" customModuleProvider="target">
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="textColor">
|
||||
<color key="value" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<tabBarItem key="tabBarItem" title="Item1" image="icon_pin" id="lUH-JS-dWf" customClass="RAMAnimatedTabBarItem" customModule="Animated_Tab_Bar" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="animation" destination="CzN-js-aQV" id="gvH-Rf-Hp8"/>
|
||||
</connections>
|
||||
</tabBarItem>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
<customObject id="CzN-js-aQV" customClass="RAMFlipLeftTransitionItemAnimations" customModule="RAMAnimatedTabBarDemo" customModuleProvider="target">
|
||||
<customObject id="CzN-js-aQV" customClass="RAMFlipLeftTransitionItemAnimations" customModule="Animated_Tab_Bar" customModuleProvider="target">
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="iconSelectedColor">
|
||||
<color key="value" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
@@ -113,19 +93,12 @@
|
||||
<scene sceneID="quI-1J-que">
|
||||
<objects>
|
||||
<viewController id="DFF-lT-Wr8" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="bPS-fl-hCE"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="hbL-QY-0OH"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="DX2-Ge-a2o">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="RotationAnimation" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="juj-np-Jde">
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="348" id="5mf-z4-7zw"/>
|
||||
<constraint firstAttribute="height" constant="71" id="AvE-La-OSt"/>
|
||||
</constraints>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Rotation Animation" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="juj-np-Jde">
|
||||
<rect key="frame" x="77.5" y="317.5" width="220.5" height="32.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="27"/>
|
||||
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -133,23 +106,19 @@
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="centerY" secondItem="juj-np-Jde" secondAttribute="centerY" constant="114.5" id="5B9-09-yru"/>
|
||||
<constraint firstAttribute="centerX" secondItem="juj-np-Jde" secondAttribute="centerX" id="JZ0-P4-3th"/>
|
||||
<constraint firstAttribute="centerY" secondItem="juj-np-Jde" secondAttribute="centerY" id="5B9-09-yru"/>
|
||||
<constraint firstItem="VaI-Rh-DC9" firstAttribute="centerX" secondItem="juj-np-Jde" secondAttribute="centerX" id="JZ0-P4-3th"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="VaI-Rh-DC9"/>
|
||||
</view>
|
||||
<tabBarItem key="tabBarItem" title="Item2" image="icon_user" id="z5N-yh-KHH" customClass="RAMAnimatedTabBarItem" customModule="RAMAnimatedTabBarDemo" customModuleProvider="target">
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="textColor">
|
||||
<color key="value" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<tabBarItem key="tabBarItem" title="Item2" image="icon_user" id="z5N-yh-KHH" customClass="RAMAnimatedTabBarItem" customModule="Animated_Tab_Bar" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="animation" destination="SMy-mk-LC7" id="MkP-KN-27u"/>
|
||||
</connections>
|
||||
</tabBarItem>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="3Cn-qd-9Vu" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
<customObject id="SMy-mk-LC7" customClass="RAMLeftRotationAnimation" customModule="RAMAnimatedTabBarDemo" customModuleProvider="target">
|
||||
<customObject id="SMy-mk-LC7" customClass="RAMLeftRotationAnimation" customModule="Animated_Tab_Bar" customModuleProvider="target">
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="textSelectedColor">
|
||||
<color key="value" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
@@ -162,7 +131,7 @@
|
||||
<!--Animated Tab Bar Controller-->
|
||||
<scene sceneID="ovl-w5-59e">
|
||||
<objects>
|
||||
<tabBarController automaticallyAdjustsScrollViewInsets="NO" id="QjJ-1j-Kct" customClass="RAMAnimatedTabBarController" customModule="RAMAnimatedTabBarDemo" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tabBarController storyboardIdentifier="RAMAnimatedTabBarController" automaticallyAdjustsScrollViewInsets="NO" id="QjJ-1j-Kct" customClass="RAMAnimatedTabBarController" customModule="Animated_Tab_Bar" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<toolbarItems/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<tabBar key="tabBar" contentMode="scaleToFill" id="Xsb-sw-RJ2">
|
||||
@@ -185,31 +154,26 @@
|
||||
<!--Item4-->
|
||||
<scene sceneID="ttZ-oS-sRQ">
|
||||
<objects>
|
||||
<viewController id="eCt-4k-9Vu" customClass="ViewController" customModule="RAMAnimatedTabBarDemo" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="bHT-V9-9VP"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="KE1-We-Sek"/>
|
||||
</layoutGuides>
|
||||
<viewController id="eCt-4k-9Vu" customClass="ViewController" customModule="Animated_Tab_Bar" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="JgG-ft-dcB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Bounce Animation" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qMh-ib-nBJ">
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="348" id="8ey-6U-wVm"/>
|
||||
<constraint firstAttribute="height" constant="71" id="UZX-wq-Um3"/>
|
||||
</constraints>
|
||||
<rect key="frame" x="81.5" y="317.5" width="212" height="32.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="27"/>
|
||||
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="KK9-Py-qqm">
|
||||
<rect key="frame" x="-4" y="580" width="190.5" height="30"/>
|
||||
<state key="normal" title="Show Badge"/>
|
||||
<connections>
|
||||
<action selector="showBadgeHandelr:" destination="eCt-4k-9Vu" eventType="touchUpInside" id="ghX-V6-TVP"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FKl-OF-gs1">
|
||||
<rect key="frame" x="188.5" y="580" width="190.5" height="30"/>
|
||||
<state key="normal" title="Hide Badge"/>
|
||||
<connections>
|
||||
<action selector="hideBadgeHandler:" destination="eCt-4k-9Vu" eventType="touchUpInside" id="9Ed-dA-ULL"/>
|
||||
@@ -222,25 +186,21 @@
|
||||
<constraint firstItem="KK9-Py-qqm" firstAttribute="leading" secondItem="JgG-ft-dcB" secondAttribute="leadingMargin" constant="-20" id="Isz-OD-x14"/>
|
||||
<constraint firstItem="KK9-Py-qqm" firstAttribute="width" secondItem="FKl-OF-gs1" secondAttribute="width" id="WnW-pO-RYO"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="FKl-OF-gs1" secondAttribute="trailing" constant="-20" id="YyU-4n-KYs"/>
|
||||
<constraint firstAttribute="centerX" secondItem="qMh-ib-nBJ" secondAttribute="centerX" id="b2F-Ux-a2l"/>
|
||||
<constraint firstAttribute="centerY" secondItem="qMh-ib-nBJ" secondAttribute="centerY" constant="114.5" id="jUP-sb-8cO"/>
|
||||
<constraint firstItem="KE1-We-Sek" firstAttribute="top" secondItem="KK9-Py-qqm" secondAttribute="bottom" constant="8" id="naI-ed-60X"/>
|
||||
<constraint firstItem="KE1-We-Sek" firstAttribute="top" secondItem="FKl-OF-gs1" secondAttribute="bottom" constant="8" id="ush-0w-xgF"/>
|
||||
<constraint firstItem="kSB-yj-LRJ" firstAttribute="centerX" secondItem="qMh-ib-nBJ" secondAttribute="centerX" id="b2F-Ux-a2l"/>
|
||||
<constraint firstAttribute="centerY" secondItem="qMh-ib-nBJ" secondAttribute="centerY" id="jUP-sb-8cO"/>
|
||||
<constraint firstItem="kSB-yj-LRJ" firstAttribute="bottom" secondItem="KK9-Py-qqm" secondAttribute="bottom" constant="8" id="naI-ed-60X"/>
|
||||
<constraint firstItem="kSB-yj-LRJ" firstAttribute="bottom" secondItem="FKl-OF-gs1" secondAttribute="bottom" constant="8" id="ush-0w-xgF"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="kSB-yj-LRJ"/>
|
||||
</view>
|
||||
<tabBarItem key="tabBarItem" title="Item4" image="Settings" id="EiX-sv-bUZ" customClass="RAMAnimatedTabBarItem" customModule="RAMAnimatedTabBarDemo" customModuleProvider="target">
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="textColor">
|
||||
<color key="value" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<tabBarItem key="tabBarItem" title="Item4" image="Settings" id="EiX-sv-bUZ" customClass="RAMAnimatedTabBarItem" customModule="Animated_Tab_Bar" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="animation" destination="BSW-Za-y3b" id="Q93-Wg-KJV"/>
|
||||
</connections>
|
||||
</tabBarItem>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="4bq-TO-3KR" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
<customObject id="BSW-Za-y3b" customClass="RAMBounceAnimation" customModule="RAMAnimatedTabBarDemo" customModuleProvider="target">
|
||||
<customObject id="BSW-Za-y3b" customClass="RAMBounceAnimation" customModule="Animated_Tab_Bar" customModuleProvider="target">
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="textSelectedColor">
|
||||
<color key="value" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
@@ -257,19 +217,12 @@
|
||||
<scene sceneID="rxZ-sE-b31">
|
||||
<objects>
|
||||
<viewController id="Zsy-o9-m6D" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="lxI-Ta-Ipa"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="YWx-Sv-OdQ"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="qT7-Vb-aMC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="FrameItemAnimation" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gnW-CR-KSE">
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="348" id="CpS-Yg-h9q"/>
|
||||
<constraint firstAttribute="height" constant="71" id="cij-cm-UE5"/>
|
||||
</constraints>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Frame Animation" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gnW-CR-KSE">
|
||||
<rect key="frame" x="89.5" y="317.5" width="196.5" height="32.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="27"/>
|
||||
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -277,23 +230,19 @@
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="centerX" secondItem="gnW-CR-KSE" secondAttribute="centerX" id="jwX-bj-6Ah"/>
|
||||
<constraint firstAttribute="centerY" secondItem="gnW-CR-KSE" secondAttribute="centerY" constant="114.5" id="pMh-vB-55X"/>
|
||||
<constraint firstItem="oai-od-5ae" firstAttribute="centerX" secondItem="gnW-CR-KSE" secondAttribute="centerX" id="jwX-bj-6Ah"/>
|
||||
<constraint firstAttribute="centerY" secondItem="gnW-CR-KSE" secondAttribute="centerY" id="pMh-vB-55X"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="oai-od-5ae"/>
|
||||
</view>
|
||||
<tabBarItem key="tabBarItem" title="Item3" image="Tools_00028" id="c38-iL-qNf" customClass="RAMAnimatedTabBarItem" customModule="RAMAnimatedTabBarDemo" customModuleProvider="target">
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="textColor">
|
||||
<color key="value" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<tabBarItem key="tabBarItem" title="Item3" image="Tools_00028" id="c38-iL-qNf" customClass="RAMAnimatedTabBarItem" customModule="Animated_Tab_Bar" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="animation" destination="Ojd-WY-9Yd" id="Ogs-bO-YG5"/>
|
||||
</connections>
|
||||
</tabBarItem>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="FuQ-Du-YS3" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
<customObject id="Ojd-WY-9Yd" customClass="RAMFrameItemAnimation" customModule="RAMAnimatedTabBarDemo" customModuleProvider="target">
|
||||
<customObject id="Ojd-WY-9Yd" customClass="RAMFrameItemAnimation" customModule="Animated_Tab_Bar" customModuleProvider="target">
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="imagesPath" value="ToolsAnimation"/>
|
||||
<userDefinedRuntimeAttribute type="boolean" keyPath="isDeselectAnimation" value="YES"/>
|
||||
|
||||
@@ -1,93 +1,119 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "icon-40.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "icon-60.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "icon-58.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "icon-87.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "icon-80.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "icon-120.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "icon-120.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "icon-180.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "icon-20.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "icon-40.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "icon-29.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "icon-58.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "icon-40.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "icon-80.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "icon-76.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "icon-152.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "icon-167.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Ramotion1024.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"properties" : {
|
||||
"pre-rendered" : true
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 464 B |
|
After Width: | Height: | Size: 618 B |
|
After Width: | Height: | Size: 834 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
@@ -9,27 +9,17 @@
|
||||
import UIKit
|
||||
|
||||
class ViewController: UIViewController {
|
||||
|
||||
|
||||
var index: NSInteger = 0
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
// Do any additional setup after loading the view, typically from a nib.
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
// PRAGMA: actions
|
||||
|
||||
@IBAction func showBadgeHandelr(_ sender: AnyObject) {
|
||||
@IBAction func showBadgeHandelr(_: AnyObject) {
|
||||
// example for showing badges
|
||||
index += 1
|
||||
self.tabBarItem.badgeValue = "\(index)"
|
||||
tabBarItem.badgeValue = "\(index)"
|
||||
}
|
||||
|
||||
@IBAction func hideBadgeHandler(_ sender: AnyObject) {
|
||||
self.tabBarItem.badgeValue = nil
|
||||
|
||||
@IBAction func hideBadgeHandler(_: AnyObject) {
|
||||
tabBarItem.badgeValue = nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
//
|
||||
// RAMAnimatedTabBarDemoTests.swift
|
||||
// RAMAnimatedTabBarDemoTests
|
||||
//
|
||||
// Created by Alex Kalinkin on 11/18/14.
|
||||
// Copyright (c) 2014 Ramotion. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import XCTest
|
||||
|
||||
class RAMAnimatedTabBarDemoTests: XCTestCase {
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
func testExample() {
|
||||
// This is an example of a functional test case.
|
||||
XCTAssert(true, "Pass")
|
||||
}
|
||||
|
||||
func testPerformanceExample() {
|
||||
// This is an example of a performance test case.
|
||||
self.measureBlock() {
|
||||
// Put the code you want to measure the time of here.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,38 +1,39 @@
|
||||
[](https://ramotion.com?utm_source=gthb&utm_medium=special&utm_campaign=animated-tab-bar-logo)
|
||||
[](https://dribbble.com/shots/1766396-Animated-Tab-Bar-Icons)
|
||||
# Animated-tab-bar
|
||||
<a href="https://www.ramotion.com/agency/app-development/?utm_source=gthb&utm_medium=repo&utm_campaign=animated-tab-bar"><img src="https://github.com/Ramotion/animated-tab-bar/blob/master/header.png"></a>
|
||||
|
||||
<a href="https://github.com/Ramotion/animated-tab-bar">
|
||||
<img align="left" src="https://github.com/Ramotion/animated-tab-bar/blob/master/Screenshots/animatedTabBar.gif" width="480" height="360" /></a>
|
||||
|
||||
<p><h1 align="left">ANIMATED TAB BAR</h1></p>
|
||||
|
||||
<h4>Swift UI module library for adding animation to iOS tabbar items and icons.</h4>
|
||||
|
||||
|
||||
___
|
||||
|
||||
|
||||
|
||||
<p><h6>We specialize in the designing and coding of custom UI for Mobile Apps and Websites.</h6>
|
||||
<a href="https://www.ramotion.com/agency/app-development/?utm_source=gthb&utm_medium=repo&utm_campaign=animated-tab-bar">
|
||||
<img src="https://github.com/ramotion/gliding-collection/raw/master/contact_our_team@2x.png" width="187" height="34"></a>
|
||||
</p>
|
||||
<p><h6>Stay tuned for the latest updates:</h6>
|
||||
<a href="https://goo.gl/rPFpid" >
|
||||
<img src="https://i.imgur.com/ziSqeSo.png/" width="156" height="28"></a></p>
|
||||
|
||||
</br>
|
||||
|
||||
[](http://cocoapods.org/pods/RAMAnimatedTabBarController)
|
||||
[](http://cocoapods.org/pods/RAMAnimatedTabBarController)
|
||||
[](https://github.com/Ramotion/animated-tab-bar)
|
||||
[](https://developer.apple.com/swift/)
|
||||
[](http://twitter.com/Ramotion)
|
||||
[](https://travis-ci.org/Ramotion/animated-tab-bar)
|
||||
|
||||
## About
|
||||
This project is maintained by Ramotion, Inc.<br>
|
||||
We specialize in the designing and coding of custom UI for Mobile Apps and Websites.<br>
|
||||
|
||||
**Looking for developers for your project?**<br>
|
||||
This project is maintained by Ramotion, Inc. We specialize in the designing and coding of custom UI for Mobile Apps and Websites.
|
||||
|
||||
<a href="https://ramotion.com/?utm_source=gthb&utm_medium=special&utm_campaign=animated-tab-bar-contact-us/#Get_in_Touch">
|
||||
<img src="https://github.com/ramotion/gliding-collection/raw/master/contact_our_team@2x.png" width="187" height="34"></a>
|
||||
<br>
|
||||
|
||||
|
||||
The [iPhone mockup](https://store.ramotion.com?utm_source=gthb&utm_medium=special&utm_campaign=animated-tab-bar) available [here](https://store.ramotion.com?utm_source=gthb&utm_medium=special&utm_campaign=animated-tab-bar).
|
||||
|
||||
## Try this UI control in action
|
||||
|
||||
<a href="https://itunes.apple.com/app/apple-store/id1182360240?pt=550053&ct=gthb-animated-tab-bar&mt=8" > <img src="https://github.com/Ramotion/navigation-stack/raw/master/Download_on_the_App_Store_Badge_US-UK_135x40.png" width="170" height="58"></a>
|
||||
|
||||
Screencast from our Demo
|
||||
|
||||

|
||||
[](https://paypal.me/Ramotion)
|
||||
|
||||
## Requirements
|
||||
|
||||
- iOS 9.0+
|
||||
- xCode 8
|
||||
- Xcode 10.2
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -40,16 +41,16 @@ Just add the RAMAnimatedTabBarController folder to your project.
|
||||
|
||||
or use [CocoaPods](https://cocoapods.org) with Podfile:
|
||||
``` ruby
|
||||
pod 'RAMAnimatedTabBarController', "~> 1.5.3" swift 2.2
|
||||
pod 'RAMAnimatedTabBarController', "~> 2.0.13" swift 3
|
||||
pod 'RAMAnimatedTabBarController'
|
||||
```
|
||||
|
||||
or [Carthage](https://github.com/Carthage/Carthage) users can simply add to their `Cartfile`:
|
||||
```
|
||||
github "Ramotion/animated-tab-bar"
|
||||
|
||||
```
|
||||
|
||||
or [Swift Package Manager](https://swift.org/package-manager/)
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -119,39 +120,44 @@ class RAMBounceAnimation : RAMItemAnimation {
|
||||
playBounceAnimation(icon)
|
||||
textLabel.textColor = textSelectedColor
|
||||
}
|
||||
|
||||
|
||||
override func deselectAnimation(_ icon: UIImageView, textLabel: UILabel, defaultTextColor: UIColor, defaultIconColor: UIColor) {
|
||||
textLabel.textColor = defaultTextColor
|
||||
}
|
||||
|
||||
|
||||
override func selectedState(_ icon: UIImageView, textLabel: UILabel) {
|
||||
textLabel.textColor = textSelectedColor
|
||||
}
|
||||
|
||||
|
||||
func playBounceAnimation(_ icon : UIImageView) {
|
||||
|
||||
|
||||
let bounceAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
|
||||
bounceAnimation.values = [1.0 ,1.4, 0.9, 1.15, 0.95, 1.02, 1.0]
|
||||
bounceAnimation.duration = TimeInterval(duration)
|
||||
bounceAnimation.calculationMode = kCAAnimationCubic
|
||||
|
||||
|
||||
icon.layer.add(bounceAnimation, forKey: "bounceAnimation")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Get the Showroom App for iOS to give it a try
|
||||
Try this UI library in our iOS app. Contact us if you interested in hiring the team.
|
||||
|
||||
<a href="https://itunes.apple.com/app/apple-store/id1182360240?pt=550053&ct=animated-tab-bar&mt=8" >
|
||||
## 📄 License
|
||||
|
||||
Animated Tab Bar is released under the MIT license.
|
||||
See [LICENSE](./LICENSE) for details.
|
||||
|
||||
This library is a part of a <a href="https://github.com/Ramotion/swift-ui-animation-components-and-libraries"><b>selection of our best UI open-source projects.</b></a>
|
||||
|
||||
If you use the open-source library in your project, please make sure to credit and backlink to www.ramotion.com
|
||||
|
||||
## 📱 Get the Showroom App for iOS to give it a try
|
||||
Try this UI component and more like this in our iOS app. Contact us if interested.
|
||||
|
||||
<a href="https://itunes.apple.com/app/apple-store/id1182360240?pt=550053&ct=animated-tab-bar&mt=8" >
|
||||
<img src="https://github.com/ramotion/gliding-collection/raw/master/app_store@2x.png" width="117" height="34"></a>
|
||||
<a href="https://ramotion.com/?utm_source=gthb&utm_medium=special&utm_campaign=animated-tab-bar-contact-us/#Get_in_Touch">
|
||||
|
||||
<a href="https://www.ramotion.com/agency/app-development/?utm_source=gthb&utm_medium=repo&utm_campaign=animated-tab-bar">
|
||||
<img src="https://github.com/ramotion/gliding-collection/raw/master/contact_our_team@2x.png" width="187" height="34"></a>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
Follow us for the latest updates<br>
|
||||
[](https://twitter.com/intent/tweet?text=https://github.com/ramotion/animated-tab-bar)
|
||||
[](https://twitter.com/ramotion)
|
||||
|
||||
|
After Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 16 KiB |