UINavigationBar tint color flashing in iOS 4 - objective-c

The app I'm working on has a custom nab bar but supports iOS 4.2-iOS 5, so I need to set the UINavigationBar background and tint in this old school way in my app delegate.
#implementation UINavigationBar (UINavigationBarCategory)
- (void)drawRect:(CGRect)rect {
self.tintColor = [UIColor colorWithRed:42.0/255.0
green:164.0/255.0
blue:182.0/255.0
alpha:1.0];
UIImage *img = [UIImage imageNamed:#"navbar_bg.png"];
[img drawInRect:CGRectMake(0.0, 0.0,
self.frame.size.width,
self.frame.size.height)];
}
#end
This works for the most part, but I noticed when the app is first starting, the UIBarButtonItems flash the default navigation bar color for a second before they correct themselves and change color to match the navigation bar. Interestingly, the navigation bar itself uses the background image correctly from the get-go.
To be clear, I'm using setBackgroundImage for UINavigationBar on iOS 5 devices which works as expected so the flash is only in iOS 4.
Anyone have any insight on why this would happen and/or how to fix it?

The bar button items are the wrong color? You can manually set their tint color in viewDidLoad: to the tint color
navigationBar.rightBarButtonItem.tintColor = [UIColor ...]
if you're using a nib file. Otherwise you can do the same thing in loadView: . Either way this code will get executed as part of the initial draw loop so you'll have the proper color without any flashing.
Also for future reference, it's technically incorrect to override a method inside a category. (The latest version of Xcode, 4.3, will give you a warning about this). You should either properly subclass UINavigationBar or do "method swizzling". But that's pretty tough so don't worry about it right now :)

If you call the class with the code referenced in viewDidLoad try moving it to awakeFromNib

Related

SKStoreProductViewController title color

How do you change the title color and/or bar tint color in a SKStoreProductViewController?
I'm using the appearance API to set navigation bars to a dark color and the text to white. It changes the title color but not the bar tint color in my SKStoreProductViewController.
I don't think you can. At least not on iOS 7. On iOS 6 you can use the UIAppearance protocol and the SKSPVC will pick up the appearance you set on the UINavigationBar.
As noted on this thread, the SKSPVC is a remote view controller so it's inaccesible programmatically, meaning that you can't set it's appearance directly (or indirectly?).
Do the following to avoid the SKStoreProductViewController to take over a tintColor of value WHITE:
#define kCOLOR_NON_WHITE_COLOR [UIColor darkGrayColor]
// CHANGE ALL TINTING BEFORE WE CREATE An INSTANCE OF THIS BROKEN PIECE
[UIWindow appearance].tintColor = kCOLOR_NON_WHITE_COLOR;
[UIView appearance].tintColor = kCOLOR_NON_WHITE_COLOR;
[UINavigationBar appearance].tintColor = kCOLOR_NON_WHITE_COLOR;
[UIBarButtonItem appearance].tintColor = kCOLOR_NON_WHITE_COLOR;
// NOW CREATE THE THING
SKStoreProductViewController *controller = [[[SKStoreProductViewController alloc] init] autorelease];
This draws all the UIBarButtonItems and the UISegmentedControls in this controller in the defined color AFAIK and thus makes the controller more like your apps design.
IMPORTANT: Just do not forget(!!!) to change all the tinting back after you dismissed this controller, otherwise fresh created views in your app might take over the enforced tinting.
UPDATE: As you might already have found out the following to manipulate the appearance does not work:
[UINavigationBar appearanceWhenContainedIn:[SKStoreProductViewController class], nil]
This fix is for iOS 7 & 8 on iOS 6 you have different issues. =)

Xcode - UIDatePicker background color

My UIDatePicker's background is black (because the background for the whole screen is black probably), but I want white in the background for this UIDatePicker.
Is there any way to change the background color without subclassing it?
iOS 14 update
It looks that datePicker.backgroundColor doesn't work in iOS 14. It works. But you have to put it after preferredDatePickerStyle setting:
let picker = UIDatePicker()
if #available(iOS 13.4, *) {
picker.preferredDatePickerStyle = .wheels
}
picker.backgroundColor = .red
datePickerName.backgroundColor = [UIColor grayColor];
OBJECTIVE C
datePicker.backgroundColor = [UIColor greenColor]
SWIFT
DatePicker.backgroundColor = UIColor.blueColor()
DatePicker.setValue(UIColor.greenColor(), forKeyPath: "textColor")
DatePicker.setValue(0.8, forKeyPath: "alpha")
iOS 14 update
After iOS 14 setting background color this way
datePicker.backgroundColor = <# your bg color #>
doesn't work anymore.
So I'm using key value coding approach now:
datePicker.setValue(<# your bg color #> , forKey: "backgroundColor")
I had this same problem. I just created a UIView and put it behind the UIDatePicker
datePickerBackground = [[UIView alloc] initWithFrame:myDatePickerView.frame];
datePickerBackground.backgroundColor = [UIColor whiteColor];
[self.view insertSubview:datePickerBackground belowSubview:myDatePickerView];
I declared UIView *datePickerBackground; in my class. I reuse this same ViewController so I set datePickerBackground to nil on unLoad.
Simple follow these steps
First you set the delegate in your .h file like:
UIPickerViewDelegate, UIPickerViewDataSource
Then add that line where you created the datepicker
YourDatePicker = [[UIDatePicker alloc] init];
YourDatePicker.backgroundColor=[UIColor whiteColor];
In your case the color is white but you can change it to as you want.
Normally, I would say that UIDatePicker inherits from UIView and that you could set the background programatically via a line like yourDatePickerRef.backgroundColor = [UIColor whiteColor];, but it turns out that -- according to this related question -- UIDatePicker has a number of subviews inside of it, some of which are the backgrounds views.
It's these subviews that you need to set the background color to white (instead of clear or whatever it's currently set to).
Yes, it's a bit of a pain, but this makes UIDatePicker a potentially powerful object in terms of being able to customize the appearance of.
Why not add a plain UIView behind the picker. Set the view's background color to white. Give the view the same frame as the picker.
Note (based on your comment to Michael's answer):
Digging around the private subviews of a UIDatePicker is risky. It could break at any time. It is almost guaranteed that your solution will break for date pickers used on a device with a locale that doesn't use AM/PM since the picker will only have two components instead of three.

IOS 6 navigationController navigationbar

I just updated my phone to IOS 6 but I have some issue regarding adding UIImageView on the UINavigationController navigationbar. This is my code
UIImage *logoImage = [UIImage imageNamed:#"navigationbar.png"];
UIImageView *logoImageView = [[UIImageView alloc] initWithImage:logoImage];
UINavigationBar *navBar = self.navigationController.navigationBar;
[navBar addSubview:logoImageView];
[logoImageView release];
This will add logo on navigationbar, it works great on the lower version of IOS 6. But on IOS 6 the logo shown but the back button was behind the logo so back button is not shown.
I don't want to override the UINavigationBar drawrect since I also have UINavigatioBar somewhere on the code for popup.
Any suggestions?
I think you don't need a UIImageView in IOS 6.
You can just put a background image in the UINavigationBar (for example in AppDelegate) like this:
[[UINavigationBar appearance] setBackgroundImage :[UIImage imageNamed:#"navigationbar"]];
Found a good site which explains some new user interface customisation in IOS 6:
click here

UIAppearance Remove Custom NavBar Background for UIPopoverController

I'm in the process of incorporating iOS 5's UIAppearance feature to give my universal app a unique theme. Currently, I have implemented some code in my App Delegate to give the app custom navigation bars:
UIImage *navBarImage = [[UIImage imageNamed:#"navigationBar.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(7, 7, 7, 7)];
[[UINavigationBar appearance] setBackgroundImage:navBarImage forBarMetrics:UIBarMetricsDefault];
This works well and changes all the navigation bars from Apple's plain style to a bright gradient. However, the problem I am having is that it is overriding some style that I don't want it too. My particular issue is that it overrides the navigation bar background in the iPad's UIPopoverController, creating an ugly user experience. Please tell me how to fix it.
Edit: Please note that this is an universal app and I open the image picker through a UIPopoverController on the iPad and a modal view on the iPhone/iPod. I only want to remove the custom background for the navBar on the iPad popover, not on the modal view.
How it currently looks like:
How I want it to look like:
Thanks in advance for your help,
Guvvy
Try using the +appearanceWhenContainedIn: method to remove your background-image customization from navigation bars when they’re contained in popover controllers. Something like this:
[[UINavigationBar appearanceWhenContainedIn:[UIPopoverController class], nil] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
It’s not clear from the documentation whether setting a navigation bar’s background image to nil restores its default appearance—if that doesn’t work, you might have to take the opposite approach, and provide the list of non-popover container view controllers you’re using to +appearanceWhenContainedIn:.

iphone sdk - segmentedcontrol.tintcolor not working in OS3

In my app I have a uisegmentedcontrol in the navigation bar, as the right button item.
the code:
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.tintColor = [UIColor colorWithRed:0.70 green:0.171 blue:0.1 alpha:1.0];
works in OS2 but not OS3...?
ade.
p.s. my base sdk is 3.0
Ok,
I had to do two things:
1) For views that always had the segmentedcontrol I had to set the tint color after adding the segmentedcontrol to the rightbarbuttonitem and move the code to viewDidAppear (I had it in ViewWillAppear)
2) For views that don't always have the segmentedcontrol it looked ugly using viewDidAppear as it sometimes was showing the segmentedcontrol and then removing it (when it shouldn't be shown at all). So I had to here use viewWillAppear but also set the item to nil in viewDidDisappear
ade.