iosswiftuitabbarcontrollerui-design

Custom UITabBarControlelr design


I am trying to duplicate this UITabBarController indicator at the botton of the tab bar image icon. The indicator follows the tab that is selected and interactively moves under the current selected tab. I have searched on Github but I cannot find one that is similar. I would like any advice on how I can get started on creating a similar indicater that moves interactively or if anyone knows any similar libraries.

pic1 pic2 pic3


Solution

  • I created the animated indicator with the CALayer's implicit animation. The actual process of turning this into a custom tab bar is a bit more involved, but at least you could use this as a reference:

    import UIKit
    import PlaygroundSupport
    
    class ViewController : UIViewController {
        let frame = CGRect(origin: .init(x: 0, y: 100), size: .init(width: 400, height: 100))
        lazy var stackview = UIStackView(frame: frame)
        let layer = CALayer()
        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.addSubview(stackview)
            self.stackview.distribution = .fillEqually
            self.stackview.layer.addSublayer(layer)
            
            for _ in 1...4 {
                let v = UIView()
                v.layer.borderWidth = 1
                let tap = UITapGestureRecognizer(target: self, action:  #selector(tapped))
                v.addGestureRecognizer(tap)
                self.stackview.addArrangedSubview(v)
            }
            
            self.layer.backgroundColor = UIColor.cyan.cgColor
            self.layer.frame = CGRect(origin: .zero, size: .init(width: 40, height: 10))
            let initialPosition = self.stackview.subviews[0].center
            self.layer.position = initialPosition
        }
        
        @objc func tapped(_ sender: UITapGestureRecognizer) {
            guard let v = sender.view else { return }
            let center = v.center
            self.layer.position = center
        }
    }
    
    PlaygroundPage.current.needsIndefiniteExecution = true
    PlaygroundPage.current.liveView = ViewController()