UISearchBar text color - iphone

Browsed the documentation and I couldn't find anything to change the color of UISearchBar. Does anybody know how to change it? There isn't any textColor property :/
Thx

Works on iOS 7 and later:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:#{
NSForegroundColorAttributeName : [UIColor whiteColor],
NSFontAttributeName : [UIFont systemFontOfSize:15]
}];
You may remove unused attribute as well.
UPDATE. Due to appearanceWhenContainedIn is deprecated in iOS 9, see the Dishant's answer below: https://stackoverflow.com/a/38893352/2799722

You can do the following: Just get the searchField property from the SearchBar, and then change its textColor property.
UITextField *searchField = [searchbar valueForKey:#"_searchField"];
searchField.textColor = [UIColor redColor]; //You can put any color here.
That's it! Now you manipulate the textField in any way possible.

iOS 8: See https://stackoverflow.com/a/28183058/308315
iOS 6 / 7:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setTextColor:[UIColor redColor]];

I suspect you could use techniques described in this post
Modifying the code presented there slightly, you subclass UISearchBar:
#interface SearchBar : UISearchBar {
}
#end
Then in your implementation:
- (void)layoutSubviews {
UITextField *searchField;
NSUInteger numViews = [self.subviews count];
for(int i = 0; i < numViews; i++) {
if([[self.subviews objectAtIndex:i] isKindOfClass:[UITextField class]]) {
searchField = [self.subviews objectAtIndex:i];
}
}
if(!(searchField == nil)) {
searchField.textColor = [UIColor redColor];
}
[super layoutSubviews];
}
I haven't tested either the original post's code or this code, but looks like it ought to work.
-wkw

Here's a category that adds this functionality:
#implementation UISearchBar (UISearchBar_TextColor)
- (UITextField *)field {
// HACK: This may not work in future iOS versions
for (UIView *subview in self.subviews) {
if ([subview isKindOfClass:[UITextField class]]) {
return (UITextField *)subview;
}
}
return nil;
}
- (UIColor *)textColor {
return self.field.textColor;
}
- (void)setTextColor:(UIColor *)color {
self.field.textColor = color;
}
#end

For iOS11, I found this worked:
After setting the searchController into the navigationItem, the search text was black on black. To make it white, I had to do:
searchController.searchBar.barStyle = .blackTranslucent
It was the only thing that worked for me. My app has a transparent navigation bar to let the background gradient show through, and I am guessing the SearchBar takes on that appearance since my appearance settings for UISearchBar were largely ignored with one exception:
UISearchBar.appearance().tintColor = UIColor.red
This made the Cancel button and the text insertion cursor red. The placeholder text was light gray.
Note that: UISearchBar.appearance().barStyle = .blackTranslucent did not work - it had to be set on the instance. This also had no visible effect on the search bar (it was still transparent like the navigation bar); it just made the search text white.

appearanceWhenContainedIn is deprecated in iOS 9 , so we have to use below method for iOS 9 and above.
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:#[[UISearchBar class]]]
setTintColor:[UIColor whiteColor]];

With iOS 11 the search bar is expected to become part of the navigation bar which, as you might expect, adds all kinds of new "features."
I think it's a bug but I found that I needed to do the following to change the text (and cancel button) colour:
self.searchController.searchBar.barStyle = UISearchBarStyleMinimal;
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:#[[UISearchBar class]]]
setTintColor:[UIColor whiteColor]];
I found that the bar-style, when left to "default," would make the text black no matter the tint colour, etc. When set to either Minimal or Prominent the text was visible.

Here's a cleaner approach:
UITextField *searchField = nil;
for (UIView *v in self.searchBar.subviews)
{
if ([v isKindOfClass:[UITextField class]])
{
searchField = (UITextField *)v;
break;
}
}
if (searchField)
{
searchField.textColor = [UIColor whiteColor];
}

Modified the category suggested by David Foster (#david-foster) to work on iOS 8.
static UITextField *PBFindTextFieldInView(UIView *view) {
for(UIView *subview in view.subviews) {
if([subview isKindOfClass:UITextField.class]) {
return (UITextField *)subview;
} else {
UITextField* textField = PBFindTextFieldInView(subview);
if(textField) {
return textField;
}
}
}
return nil;
}
#implementation UISearchBar (Appearance)
- (UITextField *)field {
return PBFindTextFieldInView(self);
}
- (UIColor *)textColor {
return self.field.textColor;
}
- (void)setTextColor:(UIColor *)color {
self.field.textColor = color;
}
#end

After setting the searchController in the navigationItem for iOS 11, I found that attempting to set the textColor via UIAppearance for any UITextField within a UISearchBar had no affect, but a custom appearance property that simply called the regular textColor worked just fine.
// Implement a custom appearance property via a UITextField category
#interface UITextField (SearchBarTextColor)
#property (nonatomic, strong) UIColor * textColorWorkaround UI_APPEARANCE_SELECTOR;
#end
#implementation UITextField (SearchBarTextColor)
- (UIColor *)textColorWorkaround {
return self.textColor;
}
- (void)setTextColorWorkaround:(UIColor *)textColor {
self.textColor = textColor;
}
#end
And then use as follows:
UITextField *textFieldProxy = [UITextField appearanceWhenContainedInInstancesOfClasses:#[UISearchBar.class]];
textFieldProxy.textColorWorkaround = UIColor.lightGrayColor;
P.S. The same trick helped me color the seemingly inaccessible labels of UIDatePicker and UIPickerView

Related

iOS tint textfield background of Search bar

In iOS (support for 5.x+) what is the easiest way to change the white background color of the UISearchBar textfield to be a different color? There is no tintColor property on it.
You can try with this method as,
[searchBar setSearchFieldBackgroundImage: forState:];
In versions prior to iOS 5, you can use a category as,
#implementation UISearchBar (BackgroundColor)
- (UITextField *)field {
// HACK: This may not work in future iOS versions
for (UIView *subview in self.subviews) {
if ([subview isKindOfClass:[UITextField class]]) {
return (UITextField *)subview;
}
}
return nil;
}
- (void)setTextBackgroundColor:(UIColor *)color {
self.field.backgroundColor = color;
}
#end

How to achieve similar UI with UITextField inside UITableView (UITableViewCell)?

I am looking to mimic the following UI using a UITextField within a UITableViewCell (within a UITableView). I am new to MonoTouch and I can't seem to figure out what the code would look like for this.
This is very simple. Just add a UITextField with no background color to the cell. Add the below code in your cellForRowAtIndexPath method.
UITextField *inputText = [[UITextField alloc]initWithFrame:CGRectMake(10,10,280,22)];
inputText.textAlignment = UITextAlignmentLeft;
inputText.backgroundColor = [UIColor clearColor];
inputText.placeHolder = #"Street";
[cell.contentView addSubview:inputText];
[inputText release];
The cell is a custom cell. It has some properties, a editable UITextField, and a placehold string for empty content. The following code is writed by hand, so maybe there are some bugs inside.
#interface EditableCell : UITableViewCell {
UITextField *mTextField;
}
#property UITextField *textField;
- (void)setPlaceHoldString:(NSString *)placeHolder;
#end
#implement EditableCell
#synthesize textField = mTextField;
- (void)setPlaceHoldString:(NSString *)placeHolder
{
self.textField.placeHolder = placeHolder;
}
- (UITextField *)textField
{
if (mTextField == nil) {
mTextField = [[UITextField alloc] init];
// Configure this text field.
...
[self addSubView:mTextField];
}
return mTextField;
}
- (void)dealloc
{
self.textField = nil;
[super dealloc];
}
#end

Accessing View in awakeFromNib?

I have been trying to set a UIImageView background color (see below) in awakeFromNib
[imageView setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:1.0]];
When it did not work, I realised that its probably because the view has not loaded yet and I should move the color change to viewDidLoad.
Can I just verify that I have this right?
gary
EDIT_002:
I have just started a fresh project to check this from a clean start. I setup the view the same as I always do. The results are that the controls are indeed set to (null) in the awakeFromNib. Here is what I have:
CODE:
#interface iPhone_TEST_AwakeFromNibViewController : UIViewController {
UILabel *myLabel;
UIImageView *myView;
}
#property(nonatomic, retain)IBOutlet UILabel *myLabel;
#property(nonatomic, retain)IBOutlet UIImageView *myView;
#end
.
#synthesize myLabel;
#synthesize myView;
-(void)awakeFromNib {
NSLog(#"awakeFromNib ...");
NSLog(#"myLabel: %#", [myLabel class]);
NSLog(#"myView : %#", [myView class]);
//[myLabel setText:#"AWAKE"];
[super awakeFromNib];
}
-(void)viewDidLoad {
NSLog(#"viewDidLoad ...");
NSLog(#"myLabel: %#", [myLabel class]);
NSLog(#"myView : %#", [myView class]);
//[myLabel setText:#"VIEW"];
[super viewDidLoad];
}
OUTPUT:
awakeFromNib ...
myLabel: (null)
myView : (null)
viewDidLoad ...
myLabel: UILabel
myLabel: UIImageView
I would be interested to know if this should work, from the docs it looks like it should, but given the way I usually set things up I can't quite understand why it does not in this case.
One more answer :-) It looks like you’re getting this behaviour because the controller loads the views lazily. The view is not loaded immediately, it gets loaded the first time somebody calls the view accessor. Therefore at the time you recieve awakeFromNib the NIB loading process is done, but not for the objects inside your views. See this code:
#property(retain) IBOutlet UILabel *foo;
#synthesize foo;
- (void) awakeFromNib
{
NSLog(#"#1: %i", !!foo);
[super awakeFromNib];
NSLog(#"#2: %i", !!foo);
}
- (void) viewDidLoad
{
NSLog(#"#3: %i", !!foo);
}
This logs:
#1: 0
#2: 0
#3: 1
But if you force-load the view:
- (void) awakeFromNib
{
NSLog(#"#1: %i", !!foo);
[super awakeFromNib];
[self view]; // forces view load
NSLog(#"#2: %i", !!foo);
}
The log changes into this:
#1: 0
#3: 1
#2: 1
I believe your call to super needs to be the first line in the awakeFromNib method, otherwise the elements won't be setup yet.
-(void)awakeFromNib {
[super awakeFromNib];
[imageView setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:1.0]];
[testLabel setText:#"Pants ..."];
}
I know, this post is a bit older, but I recently had a similar problem and would like to share its solution with you.
Having subclassed NSTextView, I wanted to display the row colors in alternating orders. To be able to alter the colors from outside, I added two instance vars to my subclass, XNSStripedTableView:
#interface XNSStripedTableView : NSTableView {
NSColor *pColor; // primary color
NSColor *sColor; // secondary color
}
#property (nonatomic, assign) NSColor *pColor;
#property (nonatomic, assign) NSColor *sColor;
#end
Overwriting highlightSelectionInClipRect: does the trick to set the correct color for the respective clipRect.
- (void)highlightSelectionInClipRect:(NSRect)clipRect
{
float rowHeight = [self rowHeight] + [self intercellSpacing].height;
NSRect visibleRect = [self visibleRect];
NSRect highlightRect;
highlightRect.origin = NSMakePoint(NSMinX(visibleRect), (int)(NSMinY(clipRect)/rowHeight)*rowHeight);
highlightRect.size = NSMakeSize(NSWidth(visibleRect), rowHeight - [self intercellSpacing].height);
while (NSMinY(highlightRect) < NSMaxY(clipRect)) {
NSRect clippedHighlightRect = NSIntersectionRect(highlightRect, clipRect);
int row = (int) ((NSMinY(highlightRect)+rowHeight/2.0)/rowHeight);
NSColor *rowColor = (0 == row % 2) ? sColor : pColor;
[rowColor set];
NSRectFill(clippedHighlightRect);
highlightRect.origin.y += rowHeight;
}
[super highlightSelectionInClipRect: clipRect];
}
The only problem now is, where to set the initial values for pColor and sColor? I tried awakeFromNib:, but this would cause the debugger to come up with an error. So I dug into the problem with NSLog: and found an easy but viable solution: setting the initial values in viewWillDraw:. As the objects are not created calling the method the first time, I had to check for nil.
- (void)viewWillDraw {
if ( pColor == nil )
pColor = [[NSColor colorWithSRGBRed:0.33 green:0.33 blue:0 alpha:1] retain];
if ( sColor == nil )
sColor = [[NSColor colorWithSRGBRed:0.66 green:0.66 blue:0 alpha:1] retain];
}
I do think this solution is quite nice :-) although one could reselect the names of pColor and sColor could be adjusted to be more "human readable".
Are you sure the objects are not nil? NSAssert or NSParameterAssert are your friends:
-(void) awakeFromNib {
NSParameterAssert(imageView);
NSParameterAssert(testLabel);
NSLog(#"awakeFromNib ...");
[imageView setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:1.0]];
[testLabel setText:#"Pants ..."];
[super awakeFromNib];
}
If the objects are really initialized, try to log their address and make sure that the instances that appear in viewDidLoad are the same as those in awakeFromNib:
- (void) awakeFromNib {
NSLog(#"test label #1: %#", testLabel);
}
- (void) viewDidLoad {
NSLog(#"test label #2: %#", testLabel);
}
If the numbers are the same, you can create a category to set a breakpoint on setBackgroundColor and peek in the stack trace to see what’s going on:
#implementation UIImageView (Patch)
- (void) setBackgroundColor: (UIColor*) whatever {
NSLog(#"Set a breakpoint here.");
}
#end
You can do the same trick using a custom subclass:
#interface PeekingView : UIImageView {}
#end
#implementation PeekingView
- (void) setBackgroundColor: (UIColor*) whatever {
NSLog(#"Set a breakpoint here.");
[super setBackgroundColor:whatever];
}
#end
Now you’ll set your UIViewObject to be of class PeekingView in the Interface Builder and you’ll know when anybody tries to set the background. This should catch the case where somebody overwrites the background changes after you initialize the view in awakeFromNib.
But I presume that the problem will be much more simple, ie. imageView is most probably nil.
In case you're using a UIView subclass instead of a UIViewController subclass, you can override loadView method:
- (void)loadView
{
[super loadView];
//IBOutlets are not nil here.
}

How to resize a UISwitch?

I have made a custom UISwitch (from this post). But the problem is, my custom texts are a bit long. Is there any way to resize the switch? [I tried setBounds, did not work]
Edit:
Here is the code I used:
#interface CustomUISwitch : UISwitch
- (void) setLeftLabelText: (NSString *) labelText;
- (void) setRightLabelText: (NSString *) labelText;
#end
#implementation CustomUISwitch
- (UIView *) slider
{
return [[self subviews] lastObject];
}
- (UIView *) textHolder
{
return [[[self slider] subviews] objectAtIndex:2];
}
- (UILabel *) leftLabel
{
return [[[self textHolder] subviews] objectAtIndex:0];
}
- (UILabel *) rightLabel
{
return [[[self textHolder] subviews] objectAtIndex:1];
}
- (void) setLeftLabelText: (NSString *) labelText
{
[[self leftLabel] setText:labelText];
}
- (void) setRightLabelText: (NSString *) labelText
{
[[self rightLabel] setText:labelText];
}
#end
mySwitch = [[CustomUISwitch alloc] initWithFrame:CGRectZero];
//Tried these, but did not work
//CGRect aFrame = mySwitch.frame;
//aFrame.size.width = 200;
//aFrame.size.height = 100;
//mySwitch.frame = aFrame;
[mySwitch setLeftLabelText: #"longValue1"];
[mySwitch setRightLabelText: #"longValue2"];
The simplest way is to resize it, as a view:
UISwitch *mySwitch = [[UISwitch alloc] init];
mySwitch.transform = CGAffineTransformMakeScale(0.75, 0.75);
and you don't have to care about anything else!
Here is the swift 3 version of mxg answer:
let mySwitch = UISwitch()
mySwitch.transform = CGAffineTransform(scaleX: 0.75, y: 0.75)
Many controls are meant to be a specific size. If you were implementing this yourself, you would override setFrame:, adjust the frame parameter to match your control's required size, and then pass that to [super setFrame:].
If you subclass a control that has this behavior, there's really no way to override it because your subclass will inherit the superclass's implementation of setFrame:, which modifies your frame rectangle. And there's no way to set the frame of your control without calling [super setFrame:].
You'll most likely have to inherit from UIControl and implement the properties/behaviors you want from UISwitch manually to work around this.
UISwitch is not designed to be customized.
I think the your best solution is to download one of the custom switch implementations mentioned in the other question that you referred to. Either UICustomSwitch or RCSwitch. They both should be able to handle wide labels.
There is no option for resizing uiswitch in xib, so need to create and resize it in controller class,
UISwitch *onoff = [[UISwitch alloc] initWithFrame: CGRectMake(0, 0, 10, 10)];
onoff.transform = CGAffineTransformMakeScale(0.50, 0.50);
[self.view addSubview:onoff];
If you want to resize switch put through the Storyboard or nib, You can subclass UISwitch and override awakeFromNib method:
- (void)awakeFromNib {
self.transform = CGAffineTransformMakeScale(0.75, 0.75);
}
Select the switch control and change it's class to your custom switch class.
Here is a solution in code:
UISwitch *mySwitchNewsletter = [[UISwitch alloc] initWithFrame: CGRectMake(varSettingsSwitchNewsletter_x,
varSettingsSwitchNewsletter_y,
varSettingsSwitchNewsletter_width,
varSettingsSwitchNewsletter_height)];
if (mySwitchNewsletter != nil) {
[varCommerceSettingsView addSubview:mySwitchNewsletter];
float mySwitchScaleFactor = (varSettingsSwitchNewsletter_scale / 100.0);
CGFloat dX=mySwitchNewsletter.bounds.size.width/2, dY=mySwitchNewsletter.bounds.size.height/2;
mySwitchNewsletter.transform = CGAffineTransformTranslate(CGAffineTransformScale(CGAffineTransformMakeTranslation(-dX, -dY), mySwitchScaleFactor, mySwitchScaleFactor), dX, dY);
mySwitchNewsletter release];
}
Where varSettingsSwitchNewsletter_scale is an int from 0 to 100 (%).
// Just in case someone trying to hard code UISwitch in Xcode 6.4 the following is working
// in .h
#property UISwitch * onoff;
// in .m
self.onoff = [[UISwitch alloc] initWithFrame:CGRectMake(160, 40, 0, 0)];
_onoff.transform = CGAffineTransformMakeScale(0.50, 0.50);
[self.view addSubview:self.onoff];

Custom colors in UITabBar

Is it possible to use custom colors and background images in a UITabBar? I realize that Apple would like everyone to use the same blue and gray tab bars, but is there any way to customize this?
Second, even I were to create my own TabBar-like view controller, along with custom images, would this violate Apple's Human Interface Guidelines?
I found an answer to this at Silent Mac Design.
I implemented this way:
First make a subclass of UITabBarContoller
// CustomUITabBarController.h
#import <UIKit/UIKit.h>
#interface CustomUITabBarController: UITabBarController {
IBOutlet UITabBar *tabBar1;
}
#property(nonatomic, retain) UITabBar *tabBar1;
#end
 
// CustomUITabBarController.m
#import "CustomUITabBarController.h"
#implementation CustomUITabBarController
#synthesize tabBar1;
- (void)viewDidLoad {
[super viewDidLoad];
CGRect frame = CGRectMake(0.0, 0, self.view.bounds.size.width, 48);
UIView *v = [[UIView alloc] initWithFrame:frame];
[v setBackgroundColor:[[UIColor alloc] initWithRed:1.0
green:0.0
blue:0.0
alpha:0.1]];
[tabBar1 insertSubview:v atIndex:0];
[v release];
}
#end
And in your Nib file replace the class of your TabBar Controller with CustomUITabBarController.
FYI, from iOS 5 onwards you can customize various aspects of the UITabBar, including setting its background image using the backgroundImage property.
The new UITabBar "Customizing Appearance" properties in iOS 5 are:
backgroundImage
selectedImageTintColor
selectionIndicatorImage
tintColor
Given that Apple have introduced these methods in iOS 5, then it's possible they may be more sympathetic to attempts to customize the UITabBar for earlier OSes. This website says the Twitter app uses a custom tab bar, so that might be more reason that Apple would let such an app into the App Store, it's no guarantee though!
Use Following images ( Assuming, tabBar is having 5 Tabs as follows )
Create a new project using - "TabBar Application" template & Place following code.
Contents of AppDel.h File.
#import <UIKit/UIKit.h>
#interface cTabBarAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#property (nonatomic, retain) IBOutlet UIImageView *imgV;
#end
Contents of AppDel.m File.
#import "cTabBarAppDelegate.h"
#implementation cTabBarAppDelegate
#synthesize window=_window;
#synthesize tabBarController=_tabBarController;
#synthesize imgV = _imgV;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.tabBarController.delegate=self;
self.imgV.frame=CGRectMake(0, 425, 320, 55);
[self.tabBarController.view addSubview:self.imgV];
self.tabBarController.selectedIndex=0;
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
NSUInteger index=[[tabBarController viewControllers] indexOfObject:viewController];
switch (index) {
case 0:
self.imgV.image=[UIImage imageNamed:#"tBar1.png"];
break;
case 1:
self.imgV.image=[UIImage imageNamed:#"tBar2.png"];
break;
case 2:
self.imgV.image=[UIImage imageNamed:#"tBar3.png"];
break;
case 3:
self.imgV.image=[UIImage imageNamed:#"tBar4.png"];
break;
case 4:
self.imgV.image=[UIImage imageNamed:#"tBar5.png"];
break;
default:
break;
}
return YES;
}
At the beginning of ***ViewController.m add the following might help set background image of UITabBar.
#implementation UITabBar (CustomImage)
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed: #"background.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
If you want to use custom colors for the icons (and not just the background) instead of the default gray and blue, do it like this: http://blog.theanalogguy.be/2010/10/06/custom-colored-uitabbar-icons/
Basically, you need to create complete tabbar images (background and icons and text) for each selected tab and set your UITabBarItems to no icon and no title and insert the image into the tabbar as an UIImageView in viewWillAppear:
And Apple won't mind since we are not using any private APIs.
Since iOS 7.0, you can use -[UIImage imageWithRenderingMode:] with UIImageRenderingModeAlwaysOriginal to preserve colors:
// Preserve the colors of the tabs.
UITabBarController *controller = (UITabBarController *)((UIWindow *)[UIApplication sharedApplication].windows[0]).rootViewController;
NSArray *onIcons = #[ #"tab1-on", #"tab2-on", #"tab3-on" ];
NSArray *offIcons = #[ #"tab1-off", #"tab2-off", #"tab3-off" ];
NSArray *items = controller.tabBar.items;
for (NSUInteger i = 0; i < items.count; ++i) {
UITabBarItem *item = items[i];
item.image = [[UIImage imageNamed:offIcons[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
item.selectedImage = [[UIImage imageNamed:onIcons[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
Works like a charm.
In AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UITabBar appearance] setSelectedImageTintColor:[UIColor redColor]];
return YES;
}
As far as the UITabBar class is concerned, the icons in the bar are limited to the colours: blue for selected and grey for unselected. This is because the tab bar only uses the alpha value from the icons you supply to create the image on the bar.
The bar itself is limited to being black, as far as I can remember. I've not seen anything like the 'tint' property on UINavigationBar in the docs.
I guess you could go ahead and create your own tab bar style class and do what you want with it, but I have absolutely no idea how that fits in with Apple's HIG, or whether or not they'd challenge it during the review process.
In my experience, Apple reviewers only rejected my app if I didn't use THEIR UI elements according to the HIG. They might have a different view when it's your own UI elements you're playing with.
Here's the document that says we can't change pressed or selected appearance with our icons.
https://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/MobileHIG/IconsImages/IconsImages.html#//apple_ref/doc/uid/TP40006556-CH14-SW1
It's under the heading
Icons for Navigation Bars, Toolbars, and Tab Bars
Its possible without adding any subView.
In the class where you define the tab bar set the property of the
tabBarItem to ->>
UITabBarItem *tabBarItem1 = [[self.tabBar.tabBar items] objectAtIndex:0];
[tabBarItem1 setFinishedSelectedImage:[UIImage imageNamed:#"campaigns_hover.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"campaigns.png"]];
Its a property of tabBarItem and u can change the default blue image to a custom image.
campaigns_hover.png is the selected custom image AND
campaigns.png is the custom image when not selected...
Enjoy the secret.. :)
The below code helps you to add custom colors with RGB values to ur tabBar.
self.tabBarController.tabBar.tintColor = [[UIColor alloc] initWithRed:0.00
green:0.62
blue:0.93
alpha:1.0];
You can do that without -insertSubview:atIndex, because a new UIView is not needed. You can apply a theme using QuartzCore on each view (UITabBar and it's subviews). So the UITabBar's background is added as I've described here.
Now we must apply the image on each UITabBarItem as it's background:
// UITabBar+CustomItem.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface UITabBar (CustomItem)
-(void)setSelectedItemBackground:(UIImage *)backgroundImage;
#end
Now the .m file:
// UITabBar+CustomItem.m
#implementation UITabBar (CustomItem)
#define kItemViewTag 445533 // <-- casual number
#define kItemViewOldTag 445599 // <-- casual number different from the above
-(void)setSelectedItemBackground:(UIImage *)backgroundImage {
UIView *oldView = [self viewWithTag:kImageViewItemTag];
oldView.layer.contents = nil; // <-- remove the previous background
oldView.tag = kItemViewOldTag; // <-- this will avoid problems
NSUInteger index = [self.items indexOfObject:self.selectedItem];
UIView *buttonView = [self.subviews objectAtIndex:index];
buttonView.tag = kItemViewTag;
buttonView.layer.contents = (id)backgroundImage.CGImage; // <-- add
// the new background
}
#end
You can also change the color of the selected images, as someone made here. But what I'm wondering is: can I change the color of the selected label? The answer is yes, as described below (the following works on ios 3.x/4.x, not iOS5+):
#implementation UITabBar (Custom)
#define kSelectedLabel 334499 // <-- casual number
-(void)changeCurrentSelectedLabelColor:(UIColor *)color {
UIView *labelOldView = [self viewWithTag:kSelectedLabel];
[labelOldView removeFromSuperview];
NSString *selectedText = self.selectedItem.title;
for(UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class])
isEqualToString:#"UITabBarButton"]) {
for(UIView *itemSubview in subview.subviews) {
if ([itemSubview isKindOfClass:[UILabel class]]) {
UILabel *itemLabel = (UILabel *)itemSubview;
if([itemLabel.text isEqualToString:selectedText]) {
UILabel *selectedLabel = [[UILabel alloc]
initWithFrame:itemLabel.bounds];
selectedLabel.text = itemLabel.text;
selectedLabel.textColor = color;
selectedLabel.font = itemLabel.font;
selectedLabel.tag = kSelectedLabel;
selectedLabel.backgroundColor = [UIColor clearColor];
[itemSubview addSubview:selectedLabel];
[selectedLabel release];
}
}
}
}
}
}
#end