iOS: Tabbar Tint Color - ios7

I'm creating a TabBar in code:
self = [super init];
self.tabBarController = [[UITabBarController alloc]init];
self.tabBarController.delegate = self;
self.tabBarController.navigationController.delegate = self;
//Build Model
NSArray *topLevelControllers = [self buildTopLevelControllers];
[self.tabBarController setViewControllers:topLevelControllers animated:NO];
//Inbox will be lead navigation
self.tabBarController.selectedIndex = kSelectedIndex;
[self.view addSubview:self.tabBarController.view];
self.tabBarController.customizableViewControllers = #[];
return self;
}
In App Delegate I have the following code for Tint:
[[UIView appearance] setTintColor:[ColorUtils globalTintColor]];
Problem: When the App launches, all the icons in the Tab Bar are tinted with the global color. When I select one and then unselect it, they go back to Grey (images default color).
Desired Result: When the App launches, all the buttons are Grey (Grey is the image color in the PNGs). When I tap on the tab bar icon, the color changes to the global tint color.
Tried: In the App delegate, I have added the following code and it does NOT work:
TabBarVC *tabBarVC = [[TabBarVC alloc]init];
tabBarVC.tabBarController.tabBar.tintColor = [UIColor greyColor];
tabBarVC.tabBarController.tabBar.selectedImageTintColor = [STColorUtils globalTintColor];
[[UINavigationBar appearance] setTitleTextAttributes:#{NSForegroundColorAttributeName : [ColorUtils globalTintColor]}];
[[UIView appearance] setTintColor:[ColorUtils globalTintColor]];
[self.window setRootViewController:tabBarVC];
However, if I comment out:
//[[UIView appearance] setTintColor:[ColorUtils globalTintColor]];
The icons do appear Grey, but the global tint color is iOS7 default: Blue.

There is a known issue with selectedImageTintColor in iOS 7. Last I checked this has yet to be resolved. So remove -
tabBarVC.tabBarController.tabBar.selectedImageTintColor = [STColorUtils globalTintColor];
Also you want to use the UITabBar's appearance so replace
[[UIView appearance] setTintColor:[ColorUtils globalTintColor]];
with
[[UITabBar appearance] setTintColor:[ColorUtils globalTintColor]];

this is the best solution i've found so far:
[UIView appearance].tintColor = [UIColor redColor];
// the selected image and text will still use UIView.tintColor.
// this is to tint the unselected images until they are tapped
// [UIColor grayColor] does not exactly match the default color, but it's subtle
[UIView appearanceWhenContainedIn:[UITabBar class], nil].tintColor = [UIColor grayColor];
when using swift i needed to create an objective-c file that contains a +(UIView *)viewAppearanceWhenContainedInTabBar() method to use [UIView appearanceWhenContainedIn:] method as it is not available to swift :(

change the UIWindow's tintColor property. It's applied across every UIView which is added onto this window.

Related

Objective-C: Status Bar Alpha

I am creating a custom alert view and I am setting the background of this view to a mostly alpha black, to cause the background view to appear slightly faded. This works except for with the status bar (it stays the exact same).
With the current Apple AlertView framework, when the alert view is shown, the entire background fades slightly. How can I replicate this functionality?
EDIT
None of the answers are solving this for me. Here is what I'm doing doing to open the AlertView:
[self.navigationController.view.superview addSubview:self.alertViewController.view];
Then from the custom alert view controller in viewDidLoad():
self.view.backgroundColor = COLOR_BLACK_ALPHA;
You can't change the alpha of the status bar, you can only set its appearance.
UIAlertView is an Apple component and as such uses private API's to do things that you can't.
What I suggest is that before showing your view, take a snapshot of the screen beneath it using something like this (source : Capture iPhone screen with status bar included
UIView *screenshotView = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO];
than remove the status bar, and place the image, blur the image (can be done using a blur view, or just as an effect on the image, then show your view.
If you have any questions please ask.
How about this?
UIWindow *customWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
customWindow.windowLevel = UIWindowLevelStatusBar+1;
customWindow.hidden = NO;
customWindow.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.7];
[customWindow makeKeyAndVisible];
Now inside customWindow you can add whatever you want...
You can do this by adding a custom overlay in Window before you add your custom alert view like this:
UIWindow *aMainWindow = [[UIApplication sharedApplication] keyWindow];
self.grayOverlayView = [[MyCustomAlertViewOverlay alloc] initWithFrame:aMainWindow.bounds];
self.grayOverlayView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.5];
[aMainWindow addSubview:self.grayOverlayView];
[aMainWindow addSubview:self.customAlertView];
And this is how your overlay would look like:
#implementation MyCustomAlertViewOverlay
- (void)drawRect:(CGRect)iRect {
CGContextRef aContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(aContext);
CGColorRef aGradientStartColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0].CGColor;
CGColorRef aGradientEndColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.6].CGColor;
NSArray *aColors = [NSArray arrayWithObjects:(__bridge id)aGradientStartColor, (__bridge id)aGradientEndColor, nil];
CGFloat rLocations[2] = {0.0 , 0.5};
CGColorSpaceRef rColorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef rGradient = CGGradientCreateWithColors(rColorSpace, (CFArrayRef) aColors, rLocations);
CGColorSpaceRelease(rColorSpace);
CGPoint aCenter = CGPointMake(iRect.origin.x + iRect.size.width / 2, iRect.origin.y + iRect.size.height / 2);
CGContextDrawRadialGradient(aContext, rGradient, aCenter, 0, aCenter, iRect.size.height, kCGGlyphMax);
CGContextSetRGBFillColor(aContext, 0, 0, 0, 0.0);
CGGradientRelease(rGradient);
CGContextFillRect(aContext, iRect);
CGContextRestoreGState(aContext);
}

iOS 9 Contact List buttons White on White

I realize that ABPeoplePicker has changed for iOS 9 but the functionality is still there and working for now. The issue I am having is that the "Group" and "Cancel" buttons are coming up as white on a white background. So very hard to see. The previous controller that this is coming from does make use of white buttons on its nav bar but of course the background is darker.
I have tried to use the following which works under iOS 8 but seems to do nothing under iOS 9:
[[UIBarButtonItem appearanceWhenContainedIn:[ABPeoplePickerNavigationController class], nil] setTintColor:[UIColor blueColor]];
I have tried to directly set it as well with the navigationcontroller.navbar.tintcolor property. That didn't work under 8 or 9.
How can I get these buttons to be visible on the contact page?
Update: I have also tried this which doesn't work either:
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:#[[ABPeoplePickerNavigationController class]]] setTintColor:[UIColor blueColor]];
Update 2: I tried using the new CNContactPickerViewController and it does the same thing with white on white.
I also faced this issue earlier. To fix this, you need to set tint colour for UINavigation bar like below:
[[UINavigationBar appearance] setTintColor:[UIColor blueColor]];
ex:
- (void)showContactList
{
[[UINavigationBar appearance] setTintColor:[UIColor blueColor]];
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[self presentViewController:picker animated:YES completion:nil];
}
I don't know how but this worked for me:
// Text color of navigation bar
let textAttributes = [NSForegroundColorAttributeName:UIColor.color_template_1_2()]
UINavigationBar.appearance().titleTextAttributes = textAttributes
UINavigationBar.appearance().tintColor = UIColor.color_template_1_2()
let contactPicker = CNContactPickerViewController()
contactPicker.delegate = self
contactPicker.displayedPropertyKeys =
[CNContactPhoneNumbersKey]
self.present(contactPicker, animated: true, completion: {
let textAttributes2 = [NSForegroundColorAttributeName:UIColor.white]
UINavigationBar.appearance().titleTextAttributes = textAttributes2
UINavigationBar.appearance().tintColor = UIColor.white
})

StatusBar background color in iOS7

Im working on a app compatible from ios6 onwards. in iOS 7 status bar is overlapping views and navigationbar. i want status bar in iOS 6 style. like it should appear above all UI objects, views,Viewcontroller and navigation controller. how can we achieve this?
For fixing the overlapping issue just try this link Status bar and navigation bar issue in IOS7
and for using status bar style similar to ios 6 this link may help you Change StatusBar style
In your app delegate's applicationDidFinishLaunching method:
[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackTranslucent];
Set UIStatusBarStyleBlackTranslucent/UIStatusBarStyleBlackOpaque for getting status bar similar to iOS6.
Hope this may help you
I am late for this Answer, but i just want to share what i did, which is basically
the easiest solution
First of all-> Go to your info.plist File and add Status Bar Style->Transparent Black Style(Alpha of 0.5)
Now ,here it Goes:-
Add this code in your AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Whatever your code goes here
if(kDeviceiPad){
//adding status bar for IOS7 ipad
if (IS_IOS7) {
UIView *addStatusBar = [[UIView alloc] init];
addStatusBar.frame = CGRectMake(0, 0, 1024, 20);
addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //change this to match your navigation bar
[self.window.rootViewController.view addSubview:addStatusBar];
}
}
else{
//adding status bar for IOS7 iphone
if (IS_IOS7) {
UIView *addStatusBar = [[UIView alloc] init];
addStatusBar.frame = CGRectMake(0, 0, 320, 20);
addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //You can give your own color pattern
[self.window.rootViewController.view addSubview:addStatusBar];
}
return YES;
}

Cannot set text color of Send and Cancel buttons in the mail composer when presented from the UIActivityViewController in iOS7

I am using the UIActivityViewController to share items in iOS7. When I tap on the Mail option, it pops up the mail composer, but the Cancel and Send buttons on the navigation bar and the navigation bar itself are blue, making it very difficult to read, so I want to change their color. It's working in iOS6 but not in iOS7.
I tried
[[UIBarButtonItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor redColor], UITextAttributeTextColor, [UIColor clearColor], UITextAttributeTextShadowColor, nil] forState:UIControlStateNormal];
which works in iOS6, and I tried
[[UIBarButtonItem appearance] setTintColor:[UIColor redColor]];
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];
which causes the color to flash red the first time the app is run before immediately switching back to the blue color.
Managed to change the text color of the Send and Cancel buttons, which are on the UINavigationBar in the MFMailComposerViewController (both Send and Cancel) and MFMessageComposeViewController (only Cancel), when presented from UIActivityViewController.
Using an UIActivityViewController, tap on Messageor Mail:
You'll notice that the default text color of the Send and Cancel buttons is blue:
In order to change that, in the AppDelegate.m class, in the didFinishLaunchingWithOptions method, insert the following line:
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTintColor:[UIColor whiteColor]];
This results in:
You can also use other colors, for example:
[UIColor purpleColor];
[UIColor greenColor];
How did I test this? I noticed this solution works for the following:
with Xcode 5.1, in the iOS 7.1 simulator, building as base iOS SDK 7.1 (can be chosen from selecting the project file -> Build Settings -> Base SDK. Also, selected from General -> Deployment Target -> 7.1)
with Xcode 5.1, on an iPhone 4, building as base iOS SDK 7.0 (can be chosen from selecting the project file -> Build Settings -> Base SDK. Also, selected from General -> Deployment Target -> 7.0)
with Xcode 5.1, on an iPhone 4, building as base iOS SDK 7.1 (can be chosen from selecting the project file -> Build Settings -> Base SDK. Also, selected from General -> Deployment Target -> 7.1)
It didn't work when testing with:
with Xcode 5.1, in the iOS 7.0 simulator, building as base iOS SDK 7.0 (can be chosen from selecting the project file -> Build Settings -> Base SDK. Also, selected from General -> Deployment Target -> 7.0)
Therefore it should be safe to use, as I believe the behavior on the actual device matters more than the behavior in the iOS simulator.
If anyone knows why it doesn't work in the iOS 7.0 simulator, I would like to know. :)
Bar tint color and status bar color in UIActivityViewController.
Swift 3 solution:
extension MFMailComposeViewController {
override open func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIApplication.shared.statusBarStyle = UIStatusBarStyle.lightContent
}
open override func viewDidLoad() {
super.viewDidLoad()
navigationBar.isTranslucent = false
navigationBar.isOpaque = false
navigationBar.barTintColor = UIColor.white
navigationBar.tintColor = UIColor.white
}
}
Here is what works on iOS 7.1 as of today.
Subclass the UIActivityViewController and override the following method:
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
viewControllerToPresent.view.tintColor = [UIColor whiteColor];
[super presentViewController:viewControllerToPresent animated:flag completion:^{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
if (completion) {
completion();
}
}];
}
This will make the buttons white and the status bar white.
For Swift:
self.navigationController?.presentViewController(activityViewController, animated: true, completion: { () in
UIBarButtonItem.appearance().tintColor = UIColor.whiteColor()
UINavigationBar.appearance().barTintColor = UIColor.whiteColor() // optional to change bar backgroundColor
}
This will change Send & Cancel button color to White (tested on iOS 7,8) but am still not able to make status bar text color white.( Although I have not tried that Subclass UIActivityViewController solution to change statusbar text color )
I fixed my issue by extending the UIActivityViewController and overriding the viewWillAppear and viewWilldisapper methods:
extension UIActivityViewController {
override open func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UINavigationBar.appearance().barTintColor = .white
}
open override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.isTranslucent = false
navigationController?.navigationBar.isOpaque = false
navigationController?.navigationBar.barTintColor = UIColor(red: (247/255), green: (247/255), blue: (247/255), alpha: 1)
//navigationBar.tintColor = UIColor.white
}
open override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
UINavigationBar.appearance().barTintColor = mycustomColor
}
}
This appears to be a bug with iOS 7. I've seen other reports of this online. It also doesn't appear to be fixed in iOS 7.1.
To be specific, no matter what you do, you cannot set tint colors on navigation bars for dialogs shown from the UIActivityViewController.
I had the same problem with my app where the tintColor property of UINavigationBar is white everywhere thanks to the appearance proxy. The resulting effect is that UIBarButtonItem from the mail composer view controller navigationBar were not visible (white buttons on a white navigation bar).
I have this call in my application:didFinishLaunchingWithOptions: method:
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
As it is impossible (for now ?) to access the UINavigationBar of the mail composer view controller in the UIActivityViewController, I did the following workaround which is inspired from Alex's answer:
UIColor *normalColor = [[UINavigationBar appearance] tintColor];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:dataToShare applicationActivities:nil];
[activityViewController setCompletionHandler:^(NSString *activityType, BOOL completed) {
// back to normal color
[[UINavigationBar appearance] setTintColor:normalColor];
}];
[self presentViewController:activityViewController animated:YES completion:^{
// change color temporary
[[UINavigationBar appearance] setTintColor:[UIColor colorWithRed:232.0f/255.0f green:51.0f/255.0f blue:72.0f/255.0f alpha:1.0f]];
}];
PS: this code is intented for iOS 7, but you can use [[UIBarButtonItem appearance] setTintColor:] in iOS 6 (cf Kevin van Mierlo's answer)
Well there are reasons for why we cannot change the way that the UI in apple's code is the way it is. Mostly because it is apple's. They do not allow you to edit the way the UI in MFMailComposerViewController looks in any way. If there is a way, then I have no clue about it, but I have never seen any way to do it. MFMailComposeViewController doesn't support the appearance attribute as it was created in iOS 3.0, and appearance didn't become a thing until iOS 5.0
Here is a link to the MFMailComposeViewController apple documentation: MFMailComposeViewController
Hope this helps!
If you want to set the color of the cancel and send buttons in iOS 7 you should use this:
// Change the colours of the buttons in iOS 7
[[UINavigationBar appearance] setTintColor:[UIColor redColor]];
In iOS 6 it is indeed these and you should also leave this in your code:
// Change the colours of the buttons in iOS 6
[[UIBarButtonItem appearance] setTintColor:[UIColor redColor]];
// Change the color of the the navigation bar in iOS 6 and 7
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];
Try this code for may be it will help you
[[mailComposer navigationBar] setTintColor:[UIColor blackColor]];
I couldn't get Alex's solution to work, however I have managed to get a variation of Paillou's answer to work although I had to set both the barTintColor and the titleTextAttributes in my situation:
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:applicationActivities];
activityViewController.excludedActivityTypes = #[UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, UIActivityTypeAddToReadingList, UIActivityTypePostToVimeo, UIActivityTypePostToFlickr, UIActivityTypeAirDrop];
[activityViewController setCompletionHandler:^(NSString *activityType, BOOL completed) {
// back to normal color
[[UINavigationBar appearance] setBarTintColor:AAColorInputBorder];
[[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"Avenir-Medium" size:18], NSFontAttributeName,
[UIColor whiteColor], NSForegroundColorAttributeName,
nil]];
}];
[self presentViewController:activityViewController animated:YES completion:^{
// change color temporary
[[UINavigationBar appearance] setBarTintColor:[UIColor whiteColor]];
[[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"Avenir-Medium" size:18], NSFontAttributeName,
AAColorInputBorder, NSForegroundColorAttributeName,
nil]];
Thanks Paillou!
This has worked for me:
in AppDelegate.m in the function:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
I've entered the following code:
//mail composer
[[UINavigationBar appearanceWhenContainedIn:[MFMailComposeViewController class], nil] setBarTintColor:myBackgroundColor];
[[UINavigationBar appearanceWhenContainedIn:[MFMailComposeViewController class], nil] setTintColor:myBarItemsColor];
It works just fine on iOS7 + iOS8, did not try on newer versions
For ios7 i think that you should go through this code
[[UINavigationBar appearance] setTintColor:[UIColor redColor]];
If it is also not working then try Mail Compose View Controller apple documentation available on the internet.
Before presenting the mail composer insert this line like this:
[mailComposer.navigationBar setTintColor:[UIColor whiteColor]];
[self presentViewController:mailComposer animated:YES completion:nil];
Even though I set the status bar style in application did finish launching I also needed to set it again in the completion block like this:
[self presentViewController:mailComposer animated:YES completion:^{[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];}];
I had enormous trouble with this, especially when MFMailComposeViewController/MFMessageViewController are themselves displayed by UIActivityViewController.
I resorted to using method swizzling on viewDidAppear/viewDidDisappear to undo and then redo my app's customisation of colors and fonts, with some help from https://github.com/rentzsch/jrswizzle:
SwizzledComposeViewControllers.h
#import <MessageUI/MessageUI.h>
#interface MFMailComposeViewController (GMSwizzling)
#end
#interface MFMessageComposeViewController (GMSwizzling)
#end
SwizzledComposeViewControllers.m
#import "SwizzledComposeViewControllers.h"
#import "AppDelegate.h"
#import "JRSwizzle.h"
#implementation MFMailComposeViewController (GMSwizzling)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self jr_swizzleMethod:#selector(init) withMethod:#selector(gmswizzled_init) error:nil];
[self jr_swizzleMethod:#selector(viewWillAppear:) withMethod:#selector(gmswizzled_viewWillAppear:) error:nil];
[self jr_swizzleMethod:#selector(viewWillDisappear:) withMethod:#selector(gmswizzled_viewWillDisappear:) error:nil];
});
}
- (instancetype)gmswizzled_init {
[(AppDelegate*)UIApplication.sharedApplication.delegate uncustomiseAppearance];
return [self gmswizzled_init];
}
- (void)gmswizzled_viewWillAppear:(BOOL)animated {
[(AppDelegate*)UIApplication.sharedApplication.delegate uncustomiseAppearance];
[self gmswizzled_viewWillAppear:animated];
}
- (void)gmswizzled_viewWillDisappear:(BOOL)animated {
[(AppDelegate*)UIApplication.sharedApplication.delegate customiseAppearance];
[self gmswizzled_viewWillDisappear:animated];
}
#end
#implementation MFMessageComposeViewController (GMSwizzling)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self jr_swizzleMethod:#selector(init) withMethod:#selector(gmswizzled_init) error:nil];
[self jr_swizzleMethod:#selector(viewWillAppear:) withMethod:#selector(gmswizzled_viewWillAppear:) error:nil];
[self jr_swizzleMethod:#selector(viewWillDisappear:) withMethod:#selector(gmswizzled_viewWillDisappear:) error:nil];
});
}
- (instancetype)gmswizzled_init {
[(AppDelegate*)UIApplication.sharedApplication.delegate uncustomiseAppearance];
return [self gmswizzled_init];
}
- (void)gmswizzled_viewWillAppear:(BOOL)animated {
[(AppDelegate*)UIApplication.sharedApplication.delegate uncustomiseAppearance];
[self gmswizzled_viewWillAppear:animated];
}
- (void)gmswizzled_viewWillDisappear:(BOOL)animated {
[(AppDelegate*)UIApplication.sharedApplication.delegate customiseAppearance];
[self gmswizzled_viewWillDisappear:animated];
}
#end
(I have to admit I can't recall why I uncustomised appearances both in init and viewWillAppear, but I'm fairly sure there was a reason ...).
In Swift I made an extension for UIViewController:
extension UIViewController {
func presentActivityViewController(viewControllerToPresent: UIViewController) {
self.presentViewController(viewControllerToPresent, animated: true) { _ in
UIBarButtonItem.appearance().tintColor = UIColor.whiteColor()
UINavigationBar.appearance().barTintColor = Config.primaryColor
}
}
}
When I need to present an UIActivityViewController I call:
let activityViewController = UIActivityViewController(activityItems: items, applicationActivities: [])
presentActivityViewController(activityViewController)
In Swift, on iOS9, setting
UINavigationBar.appearance().barTintColor = UIColor.greenColor() // eg
UINavigationBar.appearance().translucent = false
before presenting the activity view controller did the trick for me.
I tried many different methods in iOS 9 and 10, but this is the only one that worked. Note that I have a background image behind the navigationBar as well:
[UIApplication.sharedApplication setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
NSDictionary *attribs = #{NSForegroundColorAttributeName:UIColor.whiteColor};
UINavigationBar.appearance.titleTextAttributes = attribs;
UINavigationBar.appearance.tintColor = UIColor.whiteColor;
[UINavigationBar.appearance setBackgroundImage:[UIImage imageNamed:#"IOSNavigationBar"] forBarMetrics:UIBarMetricsDefault];
UIBarButtonItem.appearance.tintColor = UIColor.whiteColor;
You can set your appearance before presenting UIActivityViewController. Add resetting of appearance to completionWithItemsHandler of your activity VC:
setNavBarAppearance()
activityVC.completionWithItemsHandler = { [weak self] _, _, _, _ in
self?.resetNavBarAppearance()
}
present(activityVC, animated: true, completion: nil)
The only problem, that if activity is like mail sending, it is full screen. Your appearance will not be applied to current visible views. A little hacks to solve it:
setNavBarAppearance()
activityVC.completionWithItemsHandler = { [weak self] _, _, _, _ in
self?.resetNavBarAppearance()
// Hacks(choose one of them):
// 1)
self?.navigationController?.isNavigationBarHidden = true
self?.navigationController?.isNavigationBarHidden = false
// 2)
let redrawTriggerVC = UIViewController()
redrawTriggerVC.modalPresentationStyle = .popover
self.present(redrawTriggerVC, animated: false, completion: nil)
redrawTriggerVC.dismiss(animated: false, completion: nil)
}
present(activityVC, animated: true, completion: nil)
I haven't found a mechanism I liked, so for what it's worth here's mine. Part of the trouble is later versions of iOS add the capability for apps to add system-wide Share and Action Extensions. These third-party items seem to be coded all sorts of ways. Some inherit the app's nav bar style, some use their own, and some seem to assume a white nav bar (but actually inherits from the app).
This is tested on iOS 12.2.
I create an UIActivityItemSource, to which I have:
- (nullable id)activityViewController:(nonnull UIActivityViewController *)activityViewController itemForActivityType:(nullable UIActivityType)activityType {
if (activityType == UIActivityTypePrint || [activityType.lowercaseString containsString:#"extension"] || [activityType containsString:#"AssignToContact"]) {
//What a hack, but the best I can do. Seems some extensions inherit nav style from parent, others don't.
//ActionExtension is bottom row; all those I tested need this. The string comparison catches most non-OS extensions (the type is set by developer).
[[UINavigationBar appearance] setBarTintColor:[UIColor kNavigationBarBackgroundColor]]; //kNavigationBarBackgroundColor is my app's custom nav bar background color
} else {
[[UINavigationBar appearance] setBarTintColor:[UIColor whiteColor]];
}
return self.pdfData; //In my case I'm sharing a PDF as NSData - modify as needed for your shared item
}
Then in my UIActivityViewController's completionWithItemsHandler I include:
[[UINavigationBar appearance] setBarTintColor:[UIColor kNavigationBarBackgroundColor]]; //Again, this is my app's custom nav bar background color
Unrelated to the specific issue, but if you don't currently have a UIActivityItemSource you need to do something like this:
NSArray *activities=#[self]; //And set self to be a UIActivityItemSource
UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:activities applicationActivities:nil];
I'm sure this isn't 100% reliable, but worked with all extensions I tried.

UIBarButtonItem setTintColor doesn't work on iOS7

In iOS6, I used this code to make my UIBarButtonItem:
UIBarButtonItem* validate = [[UIBarButtonItem alloc]initWithTitle:#"MyTitle" style:UIBarButtonItemStylePlain target:self action:#selector(actionValidate)];
[validate setTintColor:[UIColor orangeColor]];
self.navigationItem.rightBarButtonItem = validate;
It works fine in iOS6 but in iOS7, the color of the button changes only when you push it.. How can I fix this?
In iOS7 you if you need to change the navigationBar buttons color, you must set tintColor for the navgationBar not the for specific barButton any more.
navigationController.navigationBar.tintColor = [UIColor orangeColor];
Edit: this works in iOS7, you need to do the check:
float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (systemVersion >= 7.0)
{
navigationController.navigationBar.tintColor = [UIColor orangeColor]
}
I couldn't get #Chris's method to work (iOS 8 like #Adama says).
My use case is that I want to set all UIToolbar & UINavigationBar buttons to a default colour. So using the UIAppearance API:
UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName : UIColor.redColor()], forState: .Normal)