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


68

我正在使用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]];

这会导致该颜色在应用首次运行时闪烁红色,然后立即切换回蓝色。


1
我有同样的问题。希望有人知道发生了什么。
Kevin_TA 2013年

在这里也有同样的问题...您找到解决方案/解决方法了吗?
rgomesbr

1
我不知道您是否仍在观看,但是我给出的答案是解决您的问题的方法。使用导航栏的颜色设置iOS 7按钮的颜色。
凯文·范·米洛

Answers:


76

设法更改“发送”和“取消”按钮的文本颜色,当从显示时,该按钮UINavigationBar位于MFMailComposerViewController(“发送”和“取消”)和MFMessageComposeViewController(仅“取消”)中UIActivityViewController

使用UIActivityViewController,点击MessageMail

使用UIActivityViewController

您会注意到“发送”和“取消”按钮的默认文本颜色是蓝色:

默认蓝色

为了对此进行更改,请在AppDelegate.m类的didFinishLaunchingWithOptions方法中插入以下行:

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

结果是:

变成白色

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

[UIColor purpleColor];

变成紫色

[UIColor greenColor];

变成绿色

我是如何测试的?我注意到此解决方案适用于以下情况:

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

使用以下命令进行测试时不起作用:

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

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


2
我在Xcode 5.1 iOS 7.1模拟器和iPhone 5s iOS 7.1上进行了尝试,但无法正常工作
2014年

适用于装有iOS 7.1的设备,但不适用于装有iOS 7.0的设备。使用下面的@paillou的答案进行工作
不稳定的2014年

对于快速的应用程序,等效UINavigationBar.appearance().tintColor = UIColor.whiteColor()于AppDelegate(UINavigationBarButtonItem我认为有必要直接复制它)。
Marcus Hooper 2015年

仍会更改状态栏颜色:(
迈克尔

1
这似乎对我在Swift 4中的iOS 11上起作用:UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.self]).tintColor = UIColor.white
ekscrypto

25

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

确认它可以在iOS10上正常运行,并且可以适应Swift 2.3。
alasker

您可以自由删除UIStatusBarStyle和UIColor,仅保留.lightContent和.white
alasker

最好,更优雅的解决方案。可使用按钮,但由于任何原因我无法使其与iOS10中的barTint一起使用
rmvz3

要更改标题的颜色,请添加let whiteColor = UIColor.white let attributedStringColour:NSDictionary = [NSForegroundColorAttributeName:whiteColor] navigationBar.titleTextAttributes = attributedStringColour如?[String:AnyObject]
webjunkie

1
我认为我们不应该在扩展中重写方法。
爱德华·休恩

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

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


这是从整个互联网上建议的所有内容中唯一对我有用的解决方案-谢谢@Macijej!
thgc 2014年

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解决方案来更改状态栏文本颜色)。


好吧,如果有人对最新iOS版本有解决方案,可以建议编辑,那么我很久以前还没有对最新版本进行过测试。会更新我的答案
Aks

4

我通过扩展UIActivityViewController和覆盖viewWillAppearviewWilldisapper方法来解决我的问题:

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
    }

}

3

这似乎是iOS 7的错误。我在线上也看到过其他报道。在iOS 7.1中似乎也未修复。

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


3

我的应用程序也遇到了同样的问题,这归功于外观代理,到处都是白色的tintColor属性UINavigationBar。产生的结果是,UIBarButtonItem从邮件编辑器视图控制器的NavigationBar不可见(白色导航栏上的白色按钮)。

我的方法中有这个调用application:didFinishLaunchingWithOptions:

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

由于目前尚无法访问UINavigationBar中的mail composer视图控制器UIActivityViewController,我做了以下变通办法,其灵感来自亚历克斯的回答:

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


1

嗯,为什么我们不能更改苹果代码中的UI的原由是有原因的。主要是因为它是苹果的。它们不允许您以任何方式编辑MFMailComposerViewController中的UI外观。如果有办法,那我就不知道了,但我从未见过任何办法。MFMailComposeViewController不支持在iOS 3.0中创建的外观属性,并且直到iOS 5.0外观才成为问题

这是MFMailComposeViewController苹果文档的链接:MFMailComposeViewController

希望这可以帮助!


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

1

试试这个代码可能会帮助您

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

1

我无法使用Alex的解决方案,但是尽管必须在我的情况下同时设置barTintColor和titleTextAttributes,但是我设法使Paillou的答案有所变化:

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

谢谢潘露!


我不知道为什么让事情正常工作这么复杂,但这是唯一对我有用的解决方案。我不知道像ShareKit这样的库是如何做到的……
dulgan

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上运行正常,未在较新版本上尝试


1
在iOS 9.2上对我不起作用,导航栏按钮仍然是标准的蓝色
Michael DePhillips,2016年

1
@Michael当我写的时候,iOS8是最新的-编辑答案
Eliktz '16

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)

0

对于ios7,我认为您应该通过以下代码

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

如果它也不起作用,请尝试从Internet上获得Mail Compose View Controller苹果文档。


0

在显示邮件编辑器之前,请插入以下行:

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

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

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

7
问题是关于UIActivityViewController而不是MFMailComposeViewController
Sjoerd Perfors 2014年

0

我对此有很大的麻烦,尤其是当MFMailComposeViewController/MFMessageViewControllerUIActivityViewController

https://github.com/rentzsch/jrswizzle的一些帮助下,我诉诸于在viewDidAppear/上使用swizzizz的方法viewDidDisappear来撤消,然后重做我的应用对颜色和字体的自定义:

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

(我不得不承认我不记得为什么我在init和中都未自定义外观viewWillAppear,但我很确定这是有原因的...)。


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)

0

Swift中,在iOS9上,设置

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

在介绍活动视图控制器之前,我已经完成了窍门。


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;

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的中completionWithItemsHandler,包括:

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

与特定问题无关,但是如果您当前没有UIActivityItemSource,则需要执行以下操作:

NSArray *activities=@[self]; //And set self to be a UIActivityItemSource
UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:activities applicationActivities:nil];

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.