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?
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.
Add Runtime Color attribute named "tintColor". It will change image tint color as well as title tint color.
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;
}
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
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With