从iOS7中的UIActivityViewController呈现时,无法在邮件编辑器中设置“发送”和“取消”按钮的文本颜色

时间:2013-10-14 19:50:36

标签: ios7 uiactivityviewcontroller

我正在使用UIActivityViewController在iOS7中共享项目。当我点击“邮件”选项时,它会弹出邮件编辑器,但导航栏上的“取消”和“发送”按钮以及导航栏本身都是蓝色的,这使得它很难阅读,所以我想改变它们的颜色。它适用于iOS6,但不适用于iOS7。

我试过

[[UIBarButtonItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor redColor], UITextAttributeTextColor, [UIColor clearColor], UITextAttributeTextShadowColor, nil] forState:UIControlStateNormal];

适用于iOS6,我试过

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

会导致颜色在第一次运行应用程序时闪烁红色,然后立即切换回蓝色。

20 个答案:

答案 0 :(得分:76)

管理以更改UINavigationBarMFMailComposerViewController上的发送取消按钮的文字颜色(两者都MFMessageComposeViewController展示时,发送和取消)和UIActivityViewController(仅取消)。

使用UIActivityViewController,点按MessageMail

Using an UIActivityViewController

您会注意到发送取消按钮的默认文字颜色为蓝色:

Default blue colors

为了更改它,在AppDelegate.m类中,在didFinishLaunchingWithOptions方法中,插入以下行:

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

这导致:

Changed to white

您还可以使用其他颜色,例如:

[UIColor purpleColor];

Change to purple

[UIColor greenColor];

Changed to green

我是如何测试的?我注意到这个解决方案适用于以下内容:

  • 使用Xcode 5.1,在iOS 7.1模拟器中,构建为基本iOS SDK 7.1(可以从选择项目文件中选择 - >构建设置 - >基础SDK。另外,从常规中选择 - >部署目标 - > 7.1)
  • 使用Xcode 5.1,在iPhone 4上,构建为基础iOS SDK 7.0(可以从选择项目文件中选择 - >构建设置 - >基础SDK。另外,从常规中选择 - >部署目标 - &gt ; 7.0)
  • 使用Xcode 5.1,在iPhone 4上构建为基础iOS SDK 7.1(可以从选择项目文件中选择 - >构建设置 - >基础SDK。另外,从常规中选择 - >部署目标 - &gt ; 7.1)

使用以下内容进行测试时无法正常工作:

  • 使用Xcode 5.1,在iOS 7.0模拟器中,构建为基础iOS SDK 7.0(可以从选择项目文件中选择 - >构建设置 - >基础SDK。另外,从常规中选择 - >部署目标 - > 7.0)

因此它应该是安全的,因为我相信实际设备上的行为比iOS模拟器中的行为更重要。 如果有人知道为什么它在iOS 7.0模拟器中不起作用,我想知道。 :)

答案 1 :(得分:24)

UIActivityViewController中的条纹色彩和状态栏颜色。 Swift 3解决方案:

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
    }
}

答案 2 :(得分:6)

此版本适用于iOS 7.1。

对UIActivityViewController进行子类化并覆盖以下方法:

- (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();
        }
    }];
}

这会使按钮变白,状态栏变白。

答案 3 :(得分:4)

Swift:

self.navigationController?.presentViewController(activityViewController, animated: true, completion: { () in
   UIBarButtonItem.appearance().tintColor = UIColor.whiteColor()
   UINavigationBar.appearance().barTintColor = UIColor.whiteColor() // optional to change bar backgroundColor           
}

这将更改发送& 取消按钮颜色为白色(在iOS 7,8上测试)但仍然无法使状态栏文本颜色为白色。(虽然我没有尝试过该子类UIActivityViewController解决方案来更改状态栏文字颜色)

答案 4 :(得分:3)

这似乎是iOS 7的一个错误。我在网上看过其他报道。它似乎也没有在iOS 7.1中修复。

具体而言,无论您做什么,都无法在导航栏上为UIActivityViewController显示的对话框设置色调颜色。

答案 5 :(得分:3)

我的应用程序出现了同样的问题,tintColor UINavigationBar的{​​{1}}属性在任何地方都是白色的,这要归功于外观代理。结果是来自邮件编辑器视图控制器navigationBar的UIBarButtonItem不可见(白色导航栏上的白色按钮)。

我在application:didFinishLaunchingWithOptions:方法中接听了这个电话:

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

由于不可能(现在?)访问UINavigationBar中邮件编辑器视图控制器的UIActivityViewController,我做了以下解决方法,其灵感来自Alex的回答:

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:此代码适用于iOS 7,但您可以在iOS 6中使用[[UIBarButtonItem appearance] setTintColor:](参见Kevin van Mierlo的回答)

答案 6 :(得分:2)

我通过像这样继承UIActivityViewController来解决我的问题。     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
        }
    }

答案 7 :(得分:1)

如果您想在iOS 7中设置取消和发送按钮的颜色,您应该使用:

// Change the colours of the buttons in iOS 7
[[UINavigationBar appearance] setTintColor:[UIColor redColor]];

在iOS 6中确实如此,你也应该把它留在你的代码中:

// 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]];

答案 8 :(得分:1)

您可以在显示appearance之前设置UIActivityViewController。在completionWithItemsHandler中的activity VC中添加外观重置:

setNavBarAppearance()

activityVC.completionWithItemsHandler = { [weak self] _, _, _, _ in
    self?.resetNavBarAppearance()
}

present(activityVC, animated: true, completion: nil)

唯一的问题是,如果活动类似于邮件发送,则该活动是全屏的。您的外观不会应用于当前的可见视图。一些小技巧可以解决:

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)

答案 9 :(得分:1)

这对我有用: 在AppDelegate.m中的函数:

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

我输入了以下代码:

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

它适用于iOS7 + iOS8,没有尝试更新的版本

答案 10 :(得分:1)

我无法获得Alex的解决方案,但是我设法得到Paillou工作答案的变体,尽管我必须在我的情况下同时设置barTintColor和titleTextAttributes :

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]];

谢谢Paillou!

答案 11 :(得分:1)

尝试使用此代码可能会对您有所帮助

[[mailComposer navigationBar] setTintColor:[UIColor blackColor]];

答案 12 :(得分:1)

有充分理由说明为什么我们无法改变苹果代码中UI的方式。主要是因为它是苹果的。它们不允许您编辑MFMailComposerViewController中的UI以任何方式查看的方式。如果有办法,那我就不知道了,但我从未见过任何办法。 MFMailComposeViewController不支持iOS 3.0中创建的外观属性,直到iOS 5.0才出现外观

以下是MFMailComposeViewController苹果文档的链接:MFMailComposeViewController

希望这有帮助!

答案 13 :(得分:0)

在呈现邮件作曲家之前,请按以下方式插入此行:

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

即使我在应用程序中设置了状态栏样式并完成了启动,我还需要在完成块中再次设置它,如下所示:

[self presentViewController:mailComposer animated:YES completion:^{[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];}];

答案 14 :(得分:0)

我遇到了很大的麻烦,尤其是当MFMailComposeViewController / MFMessageViewControllerUIActivityViewController显示时。

我使用viewDidAppear / viewDidDisappear上的方法调整来撤消,然后在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

(我不得不承认我无法回想起为什么我在initviewWillAppear中都没有自定义出现,但我相当确定有理由......)。

答案 15 :(得分:0)

在Swift中,我对UIViewController进行了扩展:

extension UIViewController {

    func presentActivityViewController(viewControllerToPresent: UIViewController) {
        self.presentViewController(viewControllerToPresent, animated: true) { _ in
            UIBarButtonItem.appearance().tintColor = UIColor.whiteColor()
            UINavigationBar.appearance().barTintColor = Config.primaryColor
        }
    }
}

当我需要呈现一个UIActivityViewController时,我打电话:

    let activityViewController = UIActivityViewController(activityItems: items, applicationActivities: [])
    presentActivityViewController(activityViewController)

答案 16 :(得分:0)

Swift 中,在 iOS9 上,设置

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

在展示活动视图控制器之前为我做了诀窍。

答案 17 :(得分:0)

我在iOS 9和10中尝试了很多不同的方法,但这是唯一有效的方法。请注意,我在navigationBar后面还有一个背景图片:

[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;

答案 18 :(得分:0)

对于ios7,我认为您应该阅读此代码

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

如果它也无效,请尝试在互联网上提供的Mail Compose View Controller苹果文档。

答案 19 :(得分:0)

我还没有找到我喜欢的机制,所以这是我的。麻烦的部分原因是更高版本的iOS增加了应用程序添加系统范围的“共享和操作扩展”的功能。这些第三方项目似乎以各种方式编码。有些继承了应用程序的导航栏样式,有些使用了自己的导航栏样式,有些似乎采用了白色导航栏(但实际上是继承自应用程序)。

这已在iOS 12.2上进行了测试。

我创建一个UIActivityItemSource,我拥有一个:

- (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
}

然后在我的UIActivityViewController的{​​{1}}中包括:

completionWithItemsHandler

与特定问题无关,但是如果您当前没有[[UINavigationBar appearance] setBarTintColor:[UIColor kNavigationBarBackgroundColor]]; //Again, this is my app's custom nav bar background color ,则需要执行以下操作:

UIActivityItemSource

我确定这不是100%可靠,但可以与我尝试过的所有扩展一起使用。