Compare commits

...

26 Commits

Author SHA1 Message Date
igor.k 52174249fa support right to left direction 2020-05-20 13:33:59 +03:00
Ramotion 2ea00f8238 Update README.md 2020-04-06 09:49:38 +03:00
igor.k 50d0c1feaa remove extra line 2020-01-08 13:13:22 +03:00
igor.k 445857fd92 small improvements 2020-01-08 13:11:13 +03:00
igor.k 76d074df03 fix for case when view controllers are empty 2019-11-09 01:42:52 +03:00
igor.k 3665d14c7a increment pod version 2019-11-06 13:04:02 +03:00
igor.k 1bce9a939c Merge branch 'tab-bar-parent' of https://github.com/Ramotion/animated-tab-bar 2019-11-05 18:10:15 +03:00
igor.k e546c49294 fix items text color (dark theme) 2019-11-05 18:08:38 +03:00
igor.k 205354aa41 add Ramotion icons 2019-10-29 13:16:49 +03:00
igor.k 9687519cee small improvements 2019-10-15 02:48:23 +03:00
igor.k 0c07d6d8ed versions compatibility + titlePositionAdjustment logic 2019-10-15 02:14:32 +03:00
igor.k 800567befc small improvements 2019-10-14 17:28:52 +03:00
igor.k e909d06015 item elements layout 2019-10-14 16:01:52 +03:00
igor.k f5c9a9e444 change tab bar items parent + layout logic (TODO: correct items and text positions) 2019-10-14 14:57:17 +03:00
igor.k dd12ebf6a1 Swift Package Manager supporting 2019-10-14 04:17:25 +03:00
igor.k 1799b007d7 Swift Package Manager supporting 2019-10-14 04:16:32 +03:00
igor.k 85683d5870 wip 2019-10-14 04:06:40 +03:00
igor.k eccd00bc32 small code style fix 2019-10-14 04:05:42 +03:00
Ramotion 749c4a2be2 Update README.md 2019-10-12 20:58:51 +03:00
Ramotion ab650eda04 Update README.md 2019-10-12 20:58:30 +03:00
Alex K 22f66aef17 bump version 2019-07-08 09:52:14 +03:00
Alex K 2f54635f3a Merge branch 'master' of github.com:Ramotion/animated-tab-bar 2019-06-13 09:52:21 +03:00
Alex 3fc716a0a6 Merge pull request #254 from SoriUR/feature/bottomLineHeight
Dynamic bottom line height
2019-06-13 09:50:42 +03:00
Юрий Сорокин ba3c230eae Add height constraint property 2019-06-12 20:40:52 +03:00
Юрий Сорокин 607c2fa353 Add methods for updating height constraint 2019-06-10 00:10:06 +03:00
Юрий Сорокин f6723b656b Add property for height 2019-06-10 00:09:32 +03:00
23 changed files with 483 additions and 441 deletions
+43
View File
@@ -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 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'RAMAnimatedTabBarController'
s.version = '5.0.1'
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'
@@ -24,20 +24,18 @@ import UIKit
extension RAMAnimatedTabBarController {
func createBottomLine() {
guard let currentItem = (containers.filter { $0.value.tag == 0 }).first?.value else { return }
let lineHeight: CGFloat = 2
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: lineHeight).isActive = true
container.heightAnchor.constraint(equalToConstant: bottomLineHeight).isActive = true
let line = UIView()
@@ -48,10 +46,12 @@ extension RAMAnimatedTabBarController {
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?.heightAnchor.constraint(equalToConstant: lineHeight).isActive = true
bottomLine?.widthAnchor.constraint(equalTo: currentItem.widthAnchor).isActive = true
}
@@ -66,7 +66,7 @@ extension RAMAnimatedTabBarController {
func setBottomLinePosition(index: Int, animated: Bool = true) {
guard let itemsCount = tabBar.items?.count, itemsCount > index,
let currentItem = (containers.filter { $0.value.tag == index}).first?.value else { return }
let currentItem = containers.at(index) else { return }
lineLeadingConstraint?.isActive = false
@@ -79,4 +79,11 @@ extension RAMAnimatedTabBarController {
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,180 +22,6 @@
import UIKit
// 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
}
}
}
/// 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
/// 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 = 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)
}
/**
Set deselected state without animation
*/
open func deselectedState() {
guard animation != nil && iconView != nil else {
return
}
animation.deselectedState(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 == 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
}
}
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 {
@@ -229,12 +55,23 @@ open class RAMAnimatedTabBarController: UITabBarController {
}
}
/**
Bottom line height
**/
open var bottomLineHeight: CGFloat = 2 {
didSet {
if bottomLineHeight > 0 {
updateBottomLineHeight(to: bottomLineHeight)
}
}
}
/**
Bottom line time of animations duration
**/
open var bottomLineMoveDuration: TimeInterval = 0.3
var containers: [String: UIView] = [:]
private(set) var containers: [UIView] = []
open override var viewControllers: [UIViewController]? {
didSet {
@@ -253,10 +90,29 @@ open class RAMAnimatedTabBarController: UITabBarController {
}
}
open override var selectedViewController: UIViewController? {
willSet {
guard let vc = newValue,
let index = viewControllers?.firstIndex(of: vc) else { return }
handleSelection(index: index)
}
}
var lineHeightConstraint: NSLayoutConstraint?
var lineLeadingConstraint: NSLayoutConstraint?
var bottomLine: UIView?
var arrBottomAnchor:[NSLayoutConstraint] = []
var arrViews:[UIView] = []
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
@@ -265,37 +121,9 @@ open class RAMAnimatedTabBarController: UITabBarController {
initializeContainers()
}
fileprivate func initializeContainers() {
containers.values.forEach { $0.removeFromSuperview() }
containers = createViewContainers()
if !containers.isEmpty {
createCustomIcons(containers)
}
}
override open func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animate(alongsideTransition: { (transitionCoordinatorContext) -> Void in
let orient = UIApplication.shared.statusBarOrientation
for (index, var layoutAnchor) in self.arrBottomAnchor.enumerated() {
layoutAnchor.isActive = false
switch orient {
case .portrait:
layoutAnchor = self.arrViews[index].bottomAnchor.constraint(equalTo: self.bottomLayoutGuide.topAnchor)
case .landscapeLeft,.landscapeRight :
layoutAnchor = self.arrViews[index].bottomAnchor.constraint(equalTo: self.bottomLayoutGuide.bottomAnchor)
default:
print("Anything But Portrait")
}
self.arrBottomAnchor[index] = layoutAnchor
self.arrBottomAnchor[index].isActive = true
}
self.view.updateConstraints()
self.layoutContainers()
}, completion: { (transitionCoordinatorContext) -> Void in
//refresh view once rotation is completed not in will transition as it returns incorrect frame size.Refresh here
})
@@ -303,33 +131,73 @@ open class RAMAnimatedTabBarController: UITabBarController {
}
// MARK: create methods
fileprivate func createCustomIcons(_ containers: [String: UIView]) {
if let items = tabBar.items, items.count > 5 { fatalError("More button not supported") }
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")
}
var index = 0
for item in items {
guard let container = containers["container\(items.count - 1 - index)"] else {
fatalError()
}
container.tag = index
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.translatesAutoresizingMaskIntoConstraints = false
icon.tintColor = item.iconColor
icon.highlightedImage = item.selectedImage?.withRenderingMode(renderMode)
container.addSubview(icon)
// text
let textLabel = UILabel()
if let title = item.title, !title.isEmpty {
textLabel.text = title
@@ -340,18 +208,10 @@ open class RAMAnimatedTabBarController: UITabBarController {
textLabel.textColor = item.textColor
textLabel.font = UIFont.systemFont(ofSize: item.textFontSize)
textLabel.textAlignment = NSTextAlignment.center
textLabel.translatesAutoresizingMaskIntoConstraints = false
container.backgroundColor = (items as [RAMAnimatedTabBarItem])[index].bgDefaultColor
container.addSubview(icon)
let itemSize = item.image?.size ?? CGSize(width: 30, height: 30)
createConstraints(icon, container: container, size: itemSize, 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, heightRelation: .greaterThanOrEqual)
container.backgroundColor = (items as [RAMAnimatedTabBarItem])[index].bgDefaultColor
if item.isEnabled == false {
icon.alpha = 0.5
textLabel.alpha = 0.5
@@ -368,137 +228,18 @@ open class RAMAnimatedTabBarController: UITabBarController {
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, heightRelation: NSLayoutConstraint.Relation = .equal) {
let constX = NSLayoutConstraint(item: view,
attribute: NSLayoutConstraint.Attribute.centerX,
relatedBy: NSLayoutConstraint.Relation.equal,
toItem: container,
attribute: NSLayoutConstraint.Attribute.centerX,
multiplier: 1,
constant: 0)
container.addConstraint(constX)
let constY = NSLayoutConstraint(item: view,
attribute: NSLayoutConstraint.Attribute.centerY,
relatedBy: NSLayoutConstraint.Relation.equal,
toItem: container,
attribute: NSLayoutConstraint.Attribute.centerY,
multiplier: 1,
constant: yOffset)
container.addConstraint(constY)
if let width = width {
let constW = NSLayoutConstraint(item: view,
attribute: NSLayoutConstraint.Attribute.width,
relatedBy: NSLayoutConstraint.Relation.equal,
toItem: nil,
attribute: NSLayoutConstraint.Attribute.notAnAttribute,
multiplier: 1,
constant: width)
view.addConstraint(constW)
}
if let height = height {
let constH = NSLayoutConstraint(item: view,
attribute: NSLayoutConstraint.Attribute.height,
relatedBy: heightRelation,
toItem: nil,
attribute: NSLayoutConstraint.Attribute.notAnAttribute,
multiplier: 1,
constant: height)
view.addConstraint(constH)
}
}
fileprivate func createViewContainers() -> [String: UIView] {
guard let items = tabBar.items, items.count > 0 else { return [:] }
var containersDict: [String: UIView] = [:]
for index in 0 ..< items.count {
let viewContainer = createViewContainer()
containersDict["container\(index)"] = viewContainer
}
var formatString = "H:|-(0)-[container0]"
for index in 1 ..< items.count {
formatString += "-(0)-[container\(index)(==container0)]"
}
formatString += "-(0)-|"
var constranints:[NSLayoutConstraint]!
if UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft{
constranints = NSLayoutConstraint.constraints(withVisualFormat: formatString,
options: NSLayoutConstraint.FormatOptions.directionLeftToRight,
metrics: nil,
views: (containersDict as [String: AnyObject]))
} else {
constranints = NSLayoutConstraint.constraints(withVisualFormat: formatString,
options: NSLayoutConstraint.FormatOptions.directionRightToLeft,
metrics: nil,
views: (containersDict as [String: AnyObject]))
}
view.addConstraints(constranints)
return containersDict
}
fileprivate func createViewContainer() -> UIView {
let viewContainer = UIView()
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)
arrViews.append(viewContainer)
// add constrains
if UIDevice.current.orientation.isLandscape {
let bottomAnchor = viewContainer.bottomAnchor.constraint(equalTo: bottomLayoutGuide.bottomAnchor)
self.arrBottomAnchor.append(bottomAnchor)
bottomAnchor.isActive = true
} else {
let bottomAnchor = viewContainer.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor)
self.arrBottomAnchor.append(bottomAnchor)
bottomAnchor.isActive = true
}
let constH = NSLayoutConstraint(item: viewContainer,
attribute: NSLayoutConstraint.Attribute.height,
relatedBy: NSLayoutConstraint.Relation.equal,
toItem: nil,
attribute: NSLayoutConstraint.Attribute.notAnAttribute,
multiplier: 1,
constant: 49)
viewContainer.addConstraint(constH)
return viewContainer
}
// MARK: actions
@objc open func tapHandler(_ gesture: UIGestureRecognizer) {
guard let items = tabBar.items as? [RAMAnimatedTabBarItem],
let gestureView = gesture.view else {
fatalError("items must inherit RAMAnimatedTabBarItem")
}
let currentIndex = gestureView.tag
@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 }
@@ -510,27 +251,84 @@ open class RAMAnimatedTabBarController: UITabBarController {
}
if selectedIndex != currentIndex {
let animationItem: RAMAnimatedTabBarItem = items[currentIndex]
animationItem.playAnimation()
let previousItem = items.at(selectedIndex)
let previousContainer: UIView? = previousItem?.iconView?.icon.superview
previousContainer?.backgroundColor = items[selectedIndex].bgDefaultColor
previousItem?.deselectAnimation()
let deselectItem = items[selectedIndex]
let currentItem: RAMAnimatedTabBarItem = items[currentIndex]
currentItem.playAnimation()
let currentContainer: UIView? = currentItem.iconView?.icon.superview
currentContainer?.backgroundColor = items[currentIndex].bgSelectedColor
let containerPrevious: UIView = deselectItem.iconView!.icon.superview!
containerPrevious.backgroundColor = items[selectedIndex].bgDefaultColor
deselectItem.deselectAnimation()
let container: UIView = animationItem.iconView!.icon.superview!
container.backgroundColor = items[currentIndex].bgSelectedColor
selectedIndex = gestureView.tag
} else if selectedIndex == currentIndex {
if let navVC = self.viewControllers![selectedIndex] as? UINavigationController {
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
}
}
}
@@ -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
}
}
@@ -7,6 +7,10 @@
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 */; };
@@ -70,6 +74,8 @@
/* 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>"; };
@@ -122,6 +128,14 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
3950EDDA2354974D0072BAAD /* Utilities */ = {
isa = PBXGroup;
children = (
3950EDDB235497650072BAAD /* Collection+Extensions.swift */,
);
path = Utilities;
sourceTree = "<group>";
};
5A1F33BA2126AA3D004B8735 /* AnimatedTabBarTests */ = {
isa = PBXGroup;
children = (
@@ -203,9 +217,11 @@
CE4146971A1B94170037F03C /* RAMAnimatedTabBarControlller */ = {
isa = PBXGroup;
children = (
3950EDDA2354974D0072BAAD /* Utilities */,
5AC42AE5210AFA110009889F /* BottomLine */,
84BC64201C22E41F00B89B79 /* RAMBadge */,
CE90A83F1A1C7C14002D8931 /* RAMAnimatedTabBarController.swift */,
3950EDD72354950E0072BAAD /* RAMAnimatedTabBarItem.swift */,
CE4146981A1B944D0037F03C /* Animations */,
CE41469D1A1B944D0037F03C /* RAMItemAnimationProtocol.swift */,
);
@@ -434,7 +450,9 @@
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 */,
@@ -454,7 +472,9 @@
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 */,
@@ -552,7 +572,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*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
@@ -581,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;
@@ -1,12 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="QjJ-1j-Kct">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<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>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<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>
@@ -34,11 +31,6 @@
<viewLayoutGuide key="safeArea" id="cbk-oV-z7H"/>
</view>
<tabBarItem key="tabBarItem" title="Item" image="drop" id="tS2-0E-St8" customClass="RAMAnimatedTabBarItem" customModule="Animated_Tab_Bar" 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>
<connections>
<outlet property="animation" destination="Lky-Hp-l9U" id="r67-ap-cxK"/>
</connections>
@@ -78,11 +70,6 @@
<viewLayoutGuide key="safeArea" id="8ec-QI-6Cw"/>
</view>
<tabBarItem key="tabBarItem" title="Item1" image="icon_pin" id="lUH-JS-dWf" customClass="RAMAnimatedTabBarItem" customModule="Animated_Tab_Bar" 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>
<connections>
<outlet property="animation" destination="CzN-js-aQV" id="gvH-Rf-Hp8"/>
</connections>
@@ -125,11 +112,6 @@
<viewLayoutGuide key="safeArea" id="VaI-Rh-DC9"/>
</view>
<tabBarItem key="tabBarItem" title="Item2" image="icon_user" id="z5N-yh-KHH" customClass="RAMAnimatedTabBarItem" customModule="Animated_Tab_Bar" 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>
<connections>
<outlet property="animation" destination="SMy-mk-LC7" id="MkP-KN-27u"/>
</connections>
@@ -212,11 +194,6 @@
<viewLayoutGuide key="safeArea" id="kSB-yj-LRJ"/>
</view>
<tabBarItem key="tabBarItem" title="Item4" image="Settings" id="EiX-sv-bUZ" customClass="RAMAnimatedTabBarItem" customModule="Animated_Tab_Bar" 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>
<connections>
<outlet property="animation" destination="BSW-Za-y3b" id="Q93-Wg-KJV"/>
</connections>
@@ -259,11 +236,6 @@
<viewLayoutGuide key="safeArea" id="oai-od-5ae"/>
</view>
<tabBarItem key="tabBarItem" title="Item3" image="Tools_00028" id="c38-iL-qNf" customClass="RAMAnimatedTabBarItem" customModule="Animated_Tab_Bar" 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>
<connections>
<outlet property="animation" destination="Ojd-WY-9Yd" id="Ogs-bO-YG5"/>
</connections>
@@ -1,98 +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"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Ramotion1024.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"pre-rendered" : true
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

+5 -5
View File
@@ -1,4 +1,4 @@
<a href="https://dev.ramotion.com?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://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>
@@ -13,13 +13,12 @@ ___
<p><h6>We specialize in the designing and coding of custom UI for Mobile Apps and Websites.</h6>
<a href="https://dev.ramotion.com?utm_source=gthb&utm_medium=repo&utm_campaign=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/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>
<h6><a href="https://store.ramotion.com/product/iphone-x-clay-mockups?utm_source=gthb&utm_medium=special&utm_campaign=animated-tab-bar#demo">Get Free Mockup For your project →</a></h6>
</br>
@@ -48,9 +47,10 @@ 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
@@ -157,7 +157,7 @@ Try this UI component and more like this in our iOS app. Contact us if intereste
<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://dev.ramotion.com?utm_source=gthb&utm_medium=repo&utm_campaign=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/gliding-collection/raw/master/contact_our_team@2x.png" width="187" height="34"></a>
<br>
<br>