Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set background color of active tab bar item in Swift

I'm hoping to accomplish this without the use of images, if at all possible. Is there a way to create the effect shown in the image programmatically without have to render each tab out as an image?

Every question I've reviewed on SO has the tabs saved as JPGs, which is more work than I feel it should be.

Any ideas?Tab Bar

like image 667
matcartmill Avatar asked Mar 14 '15 03:03

matcartmill


People also ask

How do I change the color of text in tab bar?

How to change tab bar text color (selected/unselected) In tab bar, there are two states of the text. One is when tab is selected and another one is when the tab is unselected. To change the text color for selected state, inside the TabBar widget, add the labelColor property and set the color.

How do you give the background a color in Swift?

Find the view or view controller you want to change the background color of. Open it up in the interface builder and open the Attributes Inspector. Find the background color field and set it to the color you want.


3 Answers

I took a similar approach to @matcartmill but without the need for a special image. This solution is just based on your color.

// set red as selected background color
let numberOfItems = CGFloat(tabBar.items!.count)
let tabBarItemSize = CGSize(width: tabBar.frame.width / numberOfItems, height: tabBar.frame.height)
tabBar.selectionIndicatorImage = UIImage.imageWithColor(color: UIColor.red, size: tabBarItemSize).resizableImage(withCapInsets: UIEdgeInsets.zero)

// remove default border
tabBar.frame.size.width = self.view.frame.width + 4
tabBar.frame.origin.x = -2

I'm making use of the following extension of UIImage:

extension UIImage {

    class func imageWithColor(color: UIColor, size: CGSize) -> UIImage {
        let rect: CGRect = CGRectMake(0, 0, size.width, size.height)
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        color.setFill()
        UIRectFill(rect)
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }

}

I hope this helps!

for swift 4

extension UIImage {

   class func imageWithColor(color: UIColor, size: CGSize) -> UIImage {
    let rect: CGRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    color.setFill()
    UIRectFill(rect)
    let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return image
   }
}
like image 146
schickling Avatar answered Oct 01 '22 00:10

schickling


Update to SWIFT 3:

let numberOfItems = CGFloat((tabBarController?.tabBar.items!.count)!)

let tabBarItemSize = CGSize(width: (tabBarController?.tabBar.frame.width)! / numberOfItems,
                            height: (tabBarController?.tabBar.frame.height)!)

tabBarController?.tabBar.selectionIndicatorImage
    = UIImage.imageWithColor(color: UIColor.black,
                             size: tabBarItemSize).resizableImage(withCapInsets: .zero)

tabBarController?.tabBar.frame.size.width = self.view.frame.width + 4
tabBarController?.tabBar.frame.origin.x = -2

extension UIImage
{
    class func imageWithColor(color: UIColor, size: CGSize) -> UIImage
    {
        let rect: CGRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        color.setFill()
        UIRectFill(rect)
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
}
like image 28
Kevin Sabbe Avatar answered Sep 30 '22 23:09

Kevin Sabbe


So here's what I ended up doing. It's a mix of using a 640x49 PNG that's the color of the blue "highlighted" background I need.

In AppDelegate.swift:

var selectedBG = UIImage(named:"tab-selected-full")?.resizableImageWithCapInsets(UIEdgeInsetsMake(0, 0, 0, 0))
UITabBar.appearance().selectionIndicatorImage = selectedBG

And then in the first View Controller that gets loaded, I have:

tabBarController?.tabBar.frame.size.width = self.view.frame.width+4
tabBarController?.tabBar.frame.origin.x = -2

The reason for the above two lines is that, by default, Apple has a 2px border between the left and right sides of the tab bar and the tab bar items.

In the above I simply make the tab bar 4px wider, and then offset it so the border on the left falls just outside of the view, thus the border on the right will also fall outside of the view.

like image 3
matcartmill Avatar answered Sep 30 '22 23:09

matcartmill