It is not possible to set the text color of the Send and Cancel buttons in the mail composer if it is present in the UIActivityViewController in iOS7

I am using UIActivityViewController to share items in iOS7. When I click the Mail button, it gives out the mail composer, but the Cancel and Send buttons on the navigation bar and the navigation bar itself are blue, which makes it very difficult to read, so I want to change their color. It works 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 blink red when you first start the application, before immediately switching back to blue.

+67
ios7 uiactivityviewcontroller
Oct 14 '13 at 19:50
source share
20 answers

It was possible to change the text color of the Send and Cancel buttons that are on the UINavigationBar in the MFMailComposerViewController (both Send and Cancel ) and MFMessageComposeViewController ( Cancel only) if they are presented from the UIActivityViewController .

Using the UIActivityViewController, click on Message or Mail :

Using an UIActivityViewController

You will notice that the default text color for the Send and Cancel buttons is blue:

Default blue colors

To change this, in the AppDelegate.m class, in the AppDelegate.m method didFinishLaunchingWithOptions insert the following line:

 [[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTintColor:[UIColor whiteColor]]; 

It leads to:

Changed to white

You can also use other colors, for example:

[UIColor purpleColor];

Change to purple

[UIColor greenColor];

Changed to green

How did I check this? I noticed that this solution works for the following:

  • with Xcode 5.1 in iOS 7.1-simulator, creating as basic iOS SDK 7.1 (you can choose from the project file selection → Build settings → Basic SDK. Also selected from General → Deployment target → 7.1)
  • from Xcode 5.1 to iPhone 4, creating as the basic iOS SDK 7.0 (can be selected from the project file selection → Build settings → Basic SDK. Also selected from General → Deployment target → 7.0)
  • from Xcode 5.1 to iPhone 4, creating as the basic IOS SDK 7.1 (can be selected from the project file selection → Build settings → Basic SDK. Also selected from General → Deployment target → 7.1)

This did not work when testing with

  • with Xcode 5.1 in the iOS 7.0 simulator, creating as the base iOS SDK 7.0 (can be selected from the project file selection → Build settings → Basic SDK. Also selected from General → Deployment target → 7.0)

Therefore, it should be safe to use, since I believe that the behavior on the device itself is greater than the behavior in the iOS simulator. If anyone knows why it doesn’t work in iOS 7.0 simulator, I would like to know. :)

+76
Apr 12 '14 at 19:34
source share

The color of the stroke hue and the color of the status bar in the 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 } } 
+24
07 Oct '16 at 21:21
source share

Here's what works on iOS 7.1 today.

Subclass 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 result in white buttons and a white status bar.

+6
Aug 27 '14 at 15:22
source share

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 the color of the Send and Cancel buttons to white (tested on iOS 7.8), but I still can’t make the text color in the status bar white (although I have not tried the solution of the UIActivityViewController subclass to change the text of the status bar color )

+4
Feb 17 '15 at 10:31
source share

This seems to be a bug with iOS 7. I have seen other reports about this on the Internet. It also does not fix in iOS 7.1.

To be specific, no matter what you do, you cannot set hue colors in the navigation bar for dialogs shown using the UIActivityViewController.

+3
Mar 27 '14 at 12:37
source share

I had the same problem with my application where the tintColor UINavigationBar property is white everywhere thanks to the appearance proxy. As a result, it UIBarButtonItem out that the UIBarButtonItem from the composer’s view controller was not visible (white buttons on the white navigation bar).

I have this call in my application:didFinishLaunchingWithOptions: method:

 [[UINavigationBar appearance] setTintColor:[UIColor whiteColor]]; 

How is it impossible (at the moment?) To access the mail composer view controller UINavigationBar in the UIActivityViewController , I made the following workaround that is inspired by 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 for iOS 7, but you can use [[UIBarButtonItem appearance] setTintColor:] on iOS 6 (cf Kevin van Mierlo)

+3
May 20 '14 at
source share

I fixed my problem by subclassing the UIActivityViewController like this. viewWillAppear viewWilldisapper

 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 } } 
+2
Nov 01 '17 at 22:54 on
source share

Well, there are reasons why we cannot change the way the user interface in apple code is the way it is. Mostly because it is an apple. They do not allow editing the way the user interface is displayed in the MFMailComposerViewController. If there is a way, then I have no idea, but I have never seen any way to do this. MFMailComposeViewController does not support the appearance attribute since it was created in iOS 3.0, and the appearance did not become something until iOS 5.0

Here is the link to the Apple MFMailComposeViewController documentation: MFMailComposeViewController

Hope this helps!

+1
Nov 15 '13 at 15:33
source share

If you want to set the color of 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, this is indeed the case, 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]]; 
+1
Nov 21 '13 at 12:19
source share

Try this code, maybe it will help you

 [[mailComposer navigationBar] setTintColor:[UIColor blackColor]]; 
+1
Dec 02 '13 at
source share

I could not get Alex's solution to work, but I managed to get a variation of Paillou's answer to work, although I had to set both barTintColor and 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]]; UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, UIActivityTypeAddToReadingList, UIActivityTypePostToVimeo, UIActivityTypePostToFlickr, UIActivityTypeAirDrop]; 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!

+1
Jul 09 '14 at 1:10
source share

This worked for me: in AppDelegate.m in function:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

I entered the following code:

 //mail composer [[UINavigationBar appearanceWhenContainedIn:[MFMailComposeViewController class], nil] setBarTintColor:myBackgroundColor]; [[UINavigationBar appearanceWhenContainedIn:[MFMailComposeViewController class], nil] setTintColor:myBarItemsColor]; 

It works great on iOS7 + iOS8, has not tried newer versions

+1
Aug 10 '14 at 7:31
source share

You can customize your appearance before the UIActivityViewController . Add an appearance reset to the completionWithItemsHandler your activity VC :

 setNavBarAppearance() activityVC.completionWithItemsHandler = { [weak self] _, _, _, _ in self?.resetNavBarAppearance() } present(activityVC, animated: true, completion: nil) 

The only problem is that if the activity is like sending mail, then this is full-screen mode. Your appearance will not be applied to the current visible views. A little hack to solve this:

 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) 
+1
Sep 12 '18 at 13:38
source share

For ios7, I think you should pass this code

 [[UINavigationBar appearance] setTintColor:[UIColor redColor]]; 

If it also does not work, try downloading the Apple Mail Compose View Controller documentation online.

0
Dec 27 '13 at 18:53
source share

Before introducing the mail composer, insert this line as follows:

 [mailComposer.navigationBar setTintColor:[UIColor whiteColor]]; [self presentViewController:mailComposer animated:YES completion:nil]; 

Despite the fact that I set the line style in the application, completed the launch, I also needed to set it again in the completion block as follows:

 [self presentViewController:mailComposer animated:YES completion:^{[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];}]; 
0
Dec 29 '13 at 16:30
source share

I had huge problems with this, especially when the MFMailComposeViewController / MFMessageViewController themselves displays the UIActivityViewController .

I applied the swizzling method on viewDidAppear / viewDidDisappear to cancel and then re-configure the colors and fonts of my application using 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 must admit, I can’t remember why I looked unconventionally in both init and viewWillAppear , but I'm sure there was a reason ...).

0
Feb 18 '15 at
source share

In Swift, I made an extension for the 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 submit a UIActivityViewController, I call:

  let activityViewController = UIActivityViewController(activityItems: items, applicationActivities: []) presentActivityViewController(activityViewController) 
0
Apr 13 '16 at 14:16
source share

In Swift , on iOS9 , install

 UINavigationBar.appearance().barTintColor = UIColor.greenColor() // eg UINavigationBar.appearance().translucent = false 

before submitting the controller the kind of activity helped.

0
Jul 18 '16 at 12:41
source share

I tried many different methods in iOS 9 and 10, but this is the only thing that worked. Notice that I have a background image behind the navigation bar:

 [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; 
0
Sep 09 '16 at 4:15
source share

I did not find the mechanism that I liked, so for the fact that it stands here, mine. Part of the problem is that in later versions of iOS, the ability to add system-wide extensions to applications for sharing and actions has been added. These third-party items seem to be encoded in all sorts of ways. Some inherit the style of the application’s navigation bar, some use their own, and some seem to assume a white navigation bar (but actually inherit from the application).

This is tested on iOS 12.2.

I am creating a 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 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 completionWithItemsHandler I turn on:

 [[UINavigationBar appearance] setBarTintColor:[UIColor kNavigationBarBackgroundColor]]; //Again, this is my app custom nav bar background color 

It is not related to a specific problem, but if you do not 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 is not 100% reliable, but it worked with all the extensions I tried.

0
May 14 '19 at 16:17
source share



All Articles