How to block UIAppearance proxy for some control - ios

I set custom appearance to some of my UI classes.
[[UIBarButtonItem appearance] setTintColor:someColor];
...
[[UINavigationBar appearance] setBackgroundImage:someImage forBarMetrics:UIBarMetricsDefault];
So when i create UIBarButtonItem's or UINavigationBar's objects in my application they will have defined appearance.
But if want some object to have standart appearance(Not to use defined by proxy), I need to set all it's properties to default values manually.
So the quesion is: Is there any way to block using UIAppearance for some object?
Thank you.

Edit:
Its probably not 100% what you want to do but you could use appearanceWhenContainedIn.
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTintColor:[UIColor redColor]];
[[UIBarButtonItem appearanceWhenContainedIn:[UIToolbar class], nil] setTintColor:[UIColor yellowColor]];
This way you can control the behavior to a certain degree.
Setting the properties to nil will use the default appearance:
[self.navigationController.navigationBar setTintColor:nil];

Related

In Objective C, while presenting a ViewController how to change the color of NavigationBar?

I am able to change tho color of NavigationBar by giving BackgroundColor but than I am not able change the color of StatusBar. Please provide a solution.
You should change the barTintColor instead of the background color.
[self.navigationController setBarTintColor:[UIColor redNavigationBarColor]];
Chances are that you will probably need to change also the barButton color and/or the the title color and all that should probably apply to more than one screen. So, to save you some time, if you want to globally change all these, put the code below in your app delegate
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];
[[UINavigationBar appearance] setTitleTextAttributes:#{NSForegroundColorAttributeName : [UIColor whiteColor]}];
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
The code above will give you a red navigation bar with white title & buttons

Change ios8 Extension Navigation Bar color

I am working on iOS8 App Extension (Photo Editing Extension)
I have tried these method to update the Navigation Bar color, but failed:
[[UINavigationBar appearance] setBarTintColor:[UIColor yellowColor]];
[[UINavigationBar appearance] setTintColor:[UIColor blueColor]];
[[UINavigationBar appearance] setBackgroundColor:[UIColor blueColor]];
It displays a default translucent gray nav bar.
Does anybody have idea on how to change the navigation bar color in iOS8 extension?
Try self.navigationController.navigationBar.barTintColor = UIColor.yellow first.
This should work for some host apps but not all. Because some host apps configure the colors in UIAppearance settings.
I found some info in here: https://pspdfkit.com/blog/2017/action-extension/#uiappearance
According to the link above, the extension will "picks up the UIAppearance settings from its host app" and this has a higher priority than the "setColor" message you send to the instance.
In this case what you can do is to modify the plist of the extension:
In NSExtension dictionary you can add a key NSExtensionOverridesHostUIAppearance and set value to YES. This will make your extension override the UIApprearance setting of the host app. Unfortunately this is only available in iOS 10 and later.
Hope you find it helpful.
Try setting the translucency of the UINavigationBar to NO like below, I believe then it should start picking up the colours
[[UINavigationBar appearance] setTranslucent:NO];
Here's the Apple Documentation for UINavigationBar translucent property
I have put your code in the appDelegate didFinishLaunchWithOption
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[[UINavigationBar appearance] setBarTintColor:[UIColor yellowColor]];
[[UINavigationBar appearance] setTintColor:[UIColor blueColor]];
[[UINavigationBar appearance] setBackgroundColor:[UIColor blueColor]];
return YES;
}
And works...

Mail app segue (open-with) with incorrect navigation bar colors

I am currently attempting to open up the iOS mail all to create a draft with an attachment generated from my app. Here is a code snippet:
NSURL *fileLocation = [NSURL fileURLWithPath:self.site.dataFileLoc];
if(fileLocation) {
self.documentController = [UIDocumentInteractionController interactionControllerWithURL:fileLocation];
[self.documentController setDelegate:self];
[self.documentController presentOptionsMenuFromRect:self.view.bounds inView:self.view animated:YES];
}
However, what I am finding is that the navigation bar colours are completely off. In the AppDelegate, I am currently using these lines to set the global navigation bar appearance:
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navbarBackground"] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
[[UINavigationBar appearanceWhenContainedIn:[UIViewController class], nil] setShadowImage:[UIImage imageNamed:#"shadow"]];
[[UITabBar appearance] setSelectedImageTintColor:[UIColor whiteColor]];
[[UITabBar appearance] setTintColor:[UIColor whiteColor]];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:NO];
Unfortunately, the title of the mail view controller that appears is still black, despite my attempt to set the bar style to black (which should make the title white in return) and blue bar buttons. It does, however, seem to work fine for the "presentPreviewAnimated" view controller. How can I make the navigation bar of the mail view controller consistent?
Are there any nibs associated??
I usually try to avoid the desired level of UI customization (navigation bar styles, colors, custom background w/image) because drawing UI at runtime (unless dynamically required) generally gets me in trouble...
Why not mock it up in a .nib file and make use of the fancy-dance-y tools in Xcode?? Can be therapeutic to quickly obtain the desired grain of detail without having to hit run...

MFMessageComposeViewController appearance iOS 7

I have an appearance proxy that sets the barTintColor property to green on UINavigationBar
[[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:54./255 green:165./255 blue:53./255 alpha:1]];
As needed I override this using appearanceWhenContainedIn:
[[UINavigationBar appearanceWhenContainedIn:[INFSearchViewController class], nil] setBarTintColor:[UIColor colorWithWhite:0.80 alpha:1]];
This works fine.
However when I present an MFMessageComposeViewController it adheres to the UINavigationBar proxy and looks like the following.
Which obviously looks terrible, I would prefer MFMessageComposeViewController to not adhere to the proxy but attempting to do
[[UINavigationBar appearanceWhenContainedIn:[MFMessageComposeViewController class], nil] setBarTintColor:[UIColor whiteColor]];
has no affect.
What course of action should I take here?
The hacky way: set the appearance back to the default white, present the modal, set the appearance to styled when the modal returns.
Or, reverse your thinking. Leave the global appearance as the default. Then you can selectively apply the styled nav bar where appropriate.
If "where appropriate" ends up being 90% of the app, just set up a thin subclass of UIViewController (or whatever view controller you use a lot) and that use that where you want the appearance.
[[UINavigationBar appearanceWhenContainedIn:[MyStyledViewController class], nil]
setBarTintColor:[UIColor colorWithRed:54./255 green:165./255 blue:53./255 alpha:1]];
And in each .h file, set your view controller superclass to MyStyledViewController rather than plain old UIViewController.
After digging around and trying a few different suggestions I arrived at a nice, non-hacky solution using a UINavigationController subclass.
This allows me to style all wanted nav bars once using the appearance proxy, with the exception of the MFMessageComposeViewController and MFMailComposeViewController which I'd prefer to look standard in order to communicate to the user that they are using core iOS functionality.
1 - Create a UINavigationController subclass.
2 - Style your nav bar using the appearance proxy as you were, but now using appearanceWhenContainedIn:
[[UINavigationBar appearanceWhenContainedIn:[KCStyledNavController class], nil] setBarTintColor:[UIColor redColor]];
[[UINavigationBar appearanceWhenContainedIn:[KCStyledNavController class], nil] setTintColor:[UIColor whiteColor]];
3 - Go into your storyboard, select all the the UINavigationControllers you want styled and change their custom class to your styled one.

UINavigationBar appearance setBackgroundImage:nil doesn´t work on ios 5.1

i set my UINavigationBar appearance with the following line:
UIImage *navigationBarBackground = [UIImage imageNamed:#"HeaderNavBar.png"];
[[UINavigationBar appearance] setBackgroundImage:navigationBarBackground forBarMetrics:UIBarMetricsDefault];
I remove it with the following line:
[[UINavigationBar appearance] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
This works on every ios, except on ios 5.1...Does somebody know why?!
"When the contents of your view change, you do not redraw those changes directly. Instead, you invalidate the view using either the setNeedsDisplay or setNeedsDisplayInRect: method." (View Programming Guide). Do you still have that issue after redrawing the view?
See also: UIView Class Reference: setNeedsDisplay
[[UINavigationBar appearanceWhenContainedIn:[self class], nil] setBackgroundImage:navigationBarBackground forBarMetrics:UIBarMetricsDefault];
and then:
[[UINavigationBar appearanceWhenContainedIn:[self class], nil] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
It is recommended here.

Resources