Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITabBarItem Tab Bar Item Individual Selected Background Color

In my project, I am using an extension of UIImage to create change the selected background color of the tab bar items:

extension UIImage {
func imageWithColor(tintColor: UIColor) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)

    let context = UIGraphicsGetCurrentContext() as CGContextRef!
    CGContextTranslateCTM(context, 0, self.size.height)
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextSetBlendMode(context, CGBlendMode.Normal)

    let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect
    CGContextClipToMask(context, rect, self.CGImage)
    tintColor.setFill()
    CGContextFillRect(context, rect)

    let newImage = UIGraphicsGetImageFromCurrentImageContext() as UIImage
    UIGraphicsEndImageContext()

    return newImage
}

func makeImageWithColorAndSize(color: UIColor, size: CGSize) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    color.setFill()
    UIRectFill(CGRectMake(0, 0, 100, 100))
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image
}   
}

And then using that in my MainTabBarController

 class MainTabBarController: UITabBarController {
 override func viewDidLoad() {
    super.viewDidLoad()

    let itemIndex = 0
    let bgColor = UIColor(red: 194/255.0, green: 39/255.0, blue: 65/255.0, alpha: 1.0)

    let itemWidth = tabBar.frame.width / CGFloat(tabBar.items!.count)
    let frame = CGRectMake(CGFloat(itemWidth) * CGFloat(itemIndex), 0, itemWidth, tabBar.frame.height)
    let bgView = UIView(frame: frame)

    bgView.backgroundColor = bgColor
    tabBar.insertSubview(bgView, atIndex: 0)

    for item in self.tabBar.items as [UITabBarItem]! {
        if let image = item.image {
            item.image = image.imageWithColor(UIColor.whiteColor()).imageWithRenderingMode(.AlwaysOriginal)
        }


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

        // Sets the default color of the background of the UITabBar
        UITabBar.appearance().barTintColor = UIColor(red: 39/255.0, green: 39/255.0, blue: 39/255.0, alpha: 1.0)

        // 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)


        print(UITabBar.appearance().selectionIndicatorImage)



        UITabBar.appearance().selectionIndicatorImage = UIImage().makeImageWithColorAndSize(UIColor(red: 21/255.0, green: 21/255.0, blue: 21/255.0, alpha: 1.0), size: CGSizeMake(tabBar.frame.width/4, tabBar.frame.height))

    }

    // Do any additional setup after loading the view.
}

This works, but how can I change the selected background color for individual tab bar items?

like image 708
exotue Avatar asked Nov 04 '15 01:11

exotue


People also ask

How do you change the background color on a tab bar?

To change tab bar background color in Flutter, first, create a getter to return the TabBar widget and then wrap the TabBar widget inside the PreferredSize -> Material widget. Inside the Material add the color property and set the color of your choice.

How do I change the color of my tab bar in Swift?

Add Runtime Color attribute named "tintColor". It will change image tint color as well as title tint color.


4 Answers

Add this to application:didFinishLaunchingWithOptions:

UIColor *backgroundColor = [UIColor greenColor];

// set the bar background color
[[UITabBar appearance] setBackgroundImage:[AppDelegate imageFromColor:backgroundColor forSize:CGSizeMake(320, 49) withCornerRadius:0]];

// set the text color for selected state
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], UITextAttributeTextColor, nil] forState:UIControlStateSelected];
// set the text color for unselected state
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], UITextAttributeTextColor, nil] forState:UIControlStateNormal];

// set the selected icon color
[[UITabBar appearance] setTintColor:[UIColor whiteColor]];
[[UITabBar appearance] setSelectedImageTintColor:[UIColor whiteColor]];
// remove the shadow
[[UITabBar appearance] setShadowImage:nil];

// Set the dark color to selected tab (the dimmed background)
[[UITabBar appearance] setSelectionIndicatorImage:[AppDelegate imageFromColor:[UIColor colorWithRed:26/255.0 green:163/255.0 blue:133/255.0 alpha:1] forSize:CGSizeMake(64, 49) withCornerRadius:0]];

add a helper function to turn UIColor into UIImage

You may put this code to AppDelegate or anywhere else:

+ (UIImage *)imageFromColor:(UIColor *)color forSize:(CGSize)size withCornerRadius:(CGFloat)radius
{
    CGRect rect = CGRectMake(0, 0, size.width, size.height);
    UIGraphicsBeginImageContext(rect.size);

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Begin a new image that will be the new image with the rounded corners
    // (here with the size of an UIImageView)
    UIGraphicsBeginImageContext(size);

    // Add a clip before drawing anything, in the shape of an rounded rect
    [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius] addClip];
    // Draw your image
    [image drawInRect:rect];

    // Get the image, here setting the UIImageView image
    image = UIGraphicsGetImageFromCurrentImageContext();

    // Lets forget about that we were drawing
    UIGraphicsEndImageContext();

    return image;
}
like image 166
mobiledev Alex Avatar answered Sep 21 '22 08:09

mobiledev Alex


I found workaround without adding additional images

class TabBarController: UITabBarController {
override func viewDidLoad() {
    super.viewDidLoad()
    // update first item
    dispatch_async(dispatch_get_main_queue()) {
        self.setSelection(self.tabBar.selectedItem!)
    }
}

// MARK: - UITabBarDelegate handlers

override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
    clearSelections()
    setSelection(item)
}

// MARK: - Selection Methods

func setSelection(item:UITabBarItem) {
    dispatch_async(dispatch_get_main_queue()) {
        for i in 0..<self.tabBar.items!.count {
            let ii = self.tabBar.items![i]
            if(item == ii) {
                let sv = self.tabBar.subviews[i+1]
                let label:UILabel =  sv.subviews[1] as! UILabel
                print("didSelectItem \(label.text) = \(ii.title)")
                sv.backgroundColor = UIColor() // Selection color
            }
        }
    }
}

func clearSelections() {
    for s in tabBar.subviews {
        s.backgroundColor = UIColor.clearColor()
    }
}
}

In result I can set background color of selected tab enter image description here

like image 26
Exey Panteleev Avatar answered Sep 18 '22 08:09

Exey Panteleev


how can I change the selected background color for individual tab bar items

Tab bar items do not have a "selected background color". What they have, which you can set, is a selectedImage. By setting this to an image whose rendering mode is .AlwaysOriginal, you can dictate the look of the entire tab bar item image when it is selected, as opposed to when it is not selected.

like image 30
matt Avatar answered Sep 21 '22 08:09

matt


I'm giving you the most perfect and easiest way (just kidding). You can set the selectionIndicatorImage of your TabBar's appearance in AppDelegate for default like so:

    let screenWidth = UIScreen.main.bounds.width
    let tabSelectedBGImage = R.image.tabSelectedBg()?.resize(toWidth: screenWidth/3)
    UITabBar.appearance().selectionIndicatorImage = tabSelectedBGImage

I had to resize the image to the correct width, since I have 3 tabs, I need to divide the screenWidth to 3 of course. If you do not do this, the image will not fill out the width of your tab item. I'm posting this on my blog :D

enter image description here

like image 31
Glenn Posadas Avatar answered Sep 21 '22 08:09

Glenn Posadas