Skip to content

Commit

Permalink
add the animated bottom line
Browse files Browse the repository at this point in the history
  • Loading branch information
0ber committed May 3, 2018
1 parent bdfecd2 commit fbe2592
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// 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.filter { $0.value.tag == 0 }).first?.value else { return }

let lineHeight: CGFloat = 2

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


let line = UIView()
line.backgroundColor = bottomLineColor
line.translatesAutoresizingMaskIntoConstraints = false
container.addSubview(line)
bottomLine = line

lineLeadingConstraint = bottomLine?.leadingAnchor.constraint(equalTo: currentItem.leadingAnchor)
lineLeadingConstraint?.isActive = true

bottomLine?.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
bottomLine?.heightAnchor.constraint(equalToConstant: lineHeight).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.filter { $0.value.tag == index}).first?.value 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()
}
}
}
39 changes: 38 additions & 1 deletion RAMAnimatedTabBarController/RAMAnimatedTabBarController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,36 @@ open class RAMAnimatedTabBarController: UITabBarController {
open var animatedItems: [RAMAnimatedTabBarItem] {
return tabBar.items as? [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() }
}
}
}

/**
Bottom line color
**/
open var bottomLineColor: UIColor = .black {
didSet {
bottomLine?.backgroundColor = bottomLineColor
}
}

/**
Bottom line time of animations duration
**/
open var bottomLineMoveDuration: TimeInterval = 0.3

fileprivate var containers: [String: UIView] = [:]
var containers: [String: UIView] = [:]

open override var viewControllers: [UIViewController]? {
didSet {
Expand All @@ -208,6 +236,15 @@ open class RAMAnimatedTabBarController: UITabBarController {
initializeContainers()
}

open override var selectedIndex: Int {
didSet {
self.setBottomLinePosition(index: selectedIndex)
}
}

var lineLeadingConstraint: NSLayoutConstraint?
var bottomLine: UIView?

// MARK: life circle

open override func viewDidLoad() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
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, ); }; };
Expand Down Expand Up @@ -59,6 +61,7 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
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>"; };
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; };
Expand Down Expand Up @@ -162,6 +165,7 @@
children = (
84BC64201C22E41F00B89B79 /* RAMBadge */,
CE90A83F1A1C7C14002D8931 /* RAMAnimatedTabBarController.swift */,
5ADAB949209B0FA8006CCD85 /* RAMAnimatedTabBarController+BottomLine.swift */,
CE4146981A1B944D0037F03C /* Animations */,
CE41469D1A1B944D0037F03C /* RAMItemAnimationProtocol.swift */,
);
Expand Down Expand Up @@ -288,7 +292,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0910;
LastUpgradeCheck = 0930;
ORGANIZATIONNAME = Ramotion;
TargetAttributes = {
84D4B79C1DB0D35500EE38C6 = {
Expand Down Expand Up @@ -366,6 +370,7 @@
files = (
84D4B7A91DB0D37700EE38C6 /* RAMBadge.swift in Sources */,
84D4B7AF1DB0D38B00EE38C6 /* RAMTransitionItemAnimations.swift in Sources */,
5ADAB94B209B51E5006CCD85 /* RAMAnimatedTabBarController+BottomLine.swift in Sources */,
84D4B7B01DB0D38F00EE38C6 /* RAMItemAnimationProtocol.swift in Sources */,
84D4B7AB1DB0D37F00EE38C6 /* RAMFumeAnimation.swift in Sources */,
84D4B7AA1DB0D37B00EE38C6 /* RAMAnimatedTabBarController.swift in Sources */,
Expand All @@ -382,6 +387,7 @@
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 */,
Expand Down Expand Up @@ -494,12 +500,14 @@
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;
Expand Down Expand Up @@ -548,12 +556,14 @@
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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0910"
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand All @@ -26,7 +26,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
Expand All @@ -37,7 +36,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ class ViewController: UIViewController {
@IBAction func hideBadgeHandler(_: AnyObject) {
tabBarItem.badgeValue = nil
}

override func viewDidLoad() {
super.viewDidLoad()
}
}

0 comments on commit fbe2592

Please sign in to comment.