Last active
July 26, 2023 19:03
-
-
Save egzonpllana/cc5538f388d8a530e7c393e7344e57a5 to your computer and use it in GitHub Desktop.
Add Indicator View over tab bar item. (Swift 5)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Egzon Pllana on 13.4.23. | |
// Copyright © 2023 Native Coders. All rights reserved. | |
// | |
import UIKit | |
class IndicatingTabBarController: UITabBarController, UITabBarControllerDelegate { | |
// MARK: - Properties - | |
private let indicatorView: UIView = { | |
let view = UIView() | |
view.backgroundColor = .black | |
return view | |
}() | |
// Set attributes as you need here | |
private lazy var indicatorWidth: Double = tabBar.bounds.width / CGFloat(tabBar.items?.count ?? 1) | |
private var indicatorColor: UIColor = .black | |
// MARK: - Life cycle - | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
// Add the line indicator as a subview of the tab bar | |
tabBar.addSubview(indicatorView) | |
} | |
override func viewDidLayoutSubviews() { | |
super.viewDidLayoutSubviews() | |
// Position the line indicator at the bottom of the selected tab item | |
moveIndicator() | |
} | |
// MARK: - Methods - | |
func moveIndicator(at index: Int=0) { | |
let itemWidth = (tabBar.bounds.width / CGFloat(tabBar.items?.count ?? 1)) | |
let xPosition = (CGFloat(index) * itemWidth) + ((itemWidth / 2) - (indicatorWidth / 2)) | |
UIView.animate(withDuration: 0.3) { [self] in | |
self.indicatorView.frame = CGRect(x: xPosition, | |
y: 1, | |
width: self.indicatorWidth, | |
height: 1) | |
self.indicatorView.backgroundColor = self.indicatorColor | |
} | |
} | |
// MARK: - UITabBarControllerDelegate - | |
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { | |
guard let items = tabBar.items else { return } | |
moveIndicator(at: items.firstIndex(of: item) ?? 0) | |
} | |
} | |
// ------- How to use ------- // | |
// Step 1: | |
// Create new file: TabBarController | |
class TabBarController: IndicatingTabBarController { | |
// MARK: - Life cycle - | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
} | |
} | |
// Step 2: | |
// In storyboard, select tab bar controller and set its class to TabBarController. | |
// ------- Additional ------- // | |
// If you need to listen to tab bar delegate method didSelect, please do: | |
class TabBarController: IndicatingTabBarController { | |
// MARK: - Life cycle - | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
} | |
// MARK: - UITabBarControllerDelegate | |
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { | |
guard let items = tabBar.items else { return } | |
moveIndicator(at: items.firstIndex(of: item) ?? 0) | |
} | |
} | |
// Note: | |
// If you want to customize tab bar indicating view color, width, height, position, | |
// please do it inside IndicatingTabBarController. |
Hi @arjunshukla22, you should create a new class of type "UITabBarController" and use it for your tab bar controller. See line 66 on the current code snipet.
Hey Buddy ,
I got An issue When User leave Tab Bar Controller & Back to Same Controller TabBarIndicatorView view is hide.
Hi @arjunshukla22, it's a known issue by other users but I don't have time to find a fix for that. You should layout TabBarIndicatorView somewhere in TabBarViewController class. If you find any good fix for this, please let us know so we can update this gist for future users. Thank you!
Thanx For the Update .
Hi @egzonpllana, Where are you adding indicator view into tab bar?
@uzair045 update the whole implementation, now it should be working fine.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey Buddy ,
Can you please tell where you define customizeTabBarUI this Function