-1

I just want to change the background colour of one of the tab bat items. I found many links but didn't get any help from that.

Requirement: enter image description here

And, this is the way I setup my tab bar items

 let myTabBarItem3 = (self.tabBar.items?[2])! as UITabBarItem
 myTabBarItem3.image = UIImage(named: "ic_center")?.withRenderingMode(UIImageRenderingMode.alwaysOriginal)
 myTabBarItem3.selectedImage = UIImage(named: "ic_center")?.withRenderingMode(UIImageRenderingMode.alwaysOriginal)

What I want is the black colour background for centre tab bar item.

Any idea?

And yes it is not a duplicate, Because the previous answered are not accurate and to add extra subview is never a good option, So expecting some good solution from friends

Moin Shirazi
  • 4,372
  • 2
  • 26
  • 38

4 Answers4

1

If you want to change the background colour of only centre tabBarItem you can follow below code.

NOTE: All the below code is used in a custom class which extends UITabBarController as:

class tabbarVCViewController: UITabBarController, UITabBarControllerDelegate {

    // MARK: - ViewController Override Methods.
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        setupInitilView()
    }

    // MARK: - setup Initial View Methode.
    private func setupInitilView() {

        delegate = self

        // Sets the default color of the icon of the selected UITabBarItem and Title
        UITabBar.appearance().tintColor = UIColor.white

        // Sets the default color of the background of the UITabBar
        UITabBar.appearance().barTintColor = UIColor.white

        // Sets the background color of the selected UITabBarItem (using and plain colored UIImage with the width = 1/5 of the tabBar (if you have 5 items) and the height of the tabBar)
        //UITabBar.appearance().selectionIndicatorImage = UIImage().makeImageWithColorAndSize(color: UIColor.black, size: CGSize.init(width: tabBar.frame.width/4, height:  tabBar.frame.height))


        // Uses the original colors for your images, so they aren't not rendered as grey automatically.
        for item in self.tabBar.items! {
            if let image = item.image {

                //item.image = image.withRenderingMode(.alwaysTemplate)

                item.image = image.withRenderingMode(.alwaysOriginal) //Use default image colour as grey colour and your centre image default colour as white colour as your requirement.
            }
        }

         //Change the backgound colour of specific tabBarItem.

         let itemIndex:CGFloat = 2.0

         let bgColor = UIColor.black
         let itemWidth = tabBar.frame.width / CGFloat(tabBar.items!.count)
         let bgView = UIView(frame: CGRect.init(x: itemWidth * itemIndex, y: 0, width: itemWidth, height: tabBar.frame.height))
        bgView.backgroundColor = bgColor
        tabBar.insertSubview(bgView, at: 0)

    }

    // MARK: - UITabbarController Override Methods .
    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {

    }


    // MARK: - UITabBarControllerDelegate Methods
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {

        return true
    }
}

Use tabBarItem images default colour as grey according to your UI and centre tabBarItem image default colour as white colour in Asset.

And you will want to extend the UIImage class to make the plain colored image with the size you need:

extension UIImage {
    func makeImageWithColorAndSize(color: UIColor, size: CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        color.setFill()
        UIRectFill(CGRect.init(x: 0, y: 0, width: size.width, height: size.height))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
}
Nikhlesh Bagdiya
  • 4,316
  • 1
  • 19
  • 29
0

You can add a subview to the parent tabBar Then you can set a background color on the subview. Calculating the offset and width of your tabBarItem and inserting the subView under it.

let itemIndex = 2
let bgColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1.0)

let itemWidth = tabBar.frame.width / CGFloat(tabBar.items!.count)
let bgView = UIView(frame: CGRectMake(itemWidth * itemIndex, 0, itemWidth, tabBar.frame.height))
bgView.backgroundColor = bgColor
tabBar.insertSubview(bgView, atIndex: 0)
sarosh mirza
  • 702
  • 5
  • 12
0

You can use imageView to achieve this affect , try this approach

let myImageView: UIImageView = {
    let imageView = UIImageView()
    return imageView
}()

// Now add this imageView as subview and apply constraints
tabbar.addSubview(myImageView)
myImageView.translatesAutoresizingMaskIntoConstraints = false        
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:[v0(28)]", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": myImageView]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[v0(28)]", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": myImageView]))

tabbar.myImageView.image = UIImage(named: "ic_center")?.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
tabbar.myImageView.tintColor = UIColor.black
ricardopereira
  • 11,118
  • 5
  • 63
  • 81
3stud1ant3
  • 3,586
  • 2
  • 12
  • 15
0

Try this :

 UITabBar.appearance().tintColor = UIColor.pink
 UITabBar.appearance().barTintColor = UIColor.white
            if #available(iOS 10.0, *) {
                UITabBar.appearance().unselectedItemTintColor = UIColor.white
            } else {
                // Fallback on earlier versions
            }
let x = Double(UIScreen.main.bounds.width / 5.0)
let y = Double(tabBarController!.tabBar.frame.size.height)
let indicatorBackground: UIImage? = self.image(from: UIColor.black, for: CGSize(width: x, height: y))
UITabBar.appearance().selectionIndicatorImage = indicatorBackground

Helper Methods

func image(from color: UIColor, for size: CGSize) -> UIImage {
    let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
    autoreleasepool {
        UIGraphicsBeginImageContext(rect.size)
    }
    let context: CGContext? = UIGraphicsGetCurrentContext()
    context?.setFillColor(color.cgColor)
    context?.fill(rect)
    let image: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image!
}
KKRocks
  • 8,222
  • 1
  • 18
  • 84