Skip to content

Instantly share code, notes, and snippets.

@egzonpllana
Last active July 26, 2023 19:03
Show Gist options
  • Save egzonpllana/cc5538f388d8a530e7c393e7344e57a5 to your computer and use it in GitHub Desktop.
Save egzonpllana/cc5538f388d8a530e7c393e7344e57a5 to your computer and use it in GitHub Desktop.
Add Indicator View over tab bar item. (Swift 5)
//
// 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.
@egzonpllana
Copy link
Author

@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