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

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

4

20 回答 20

76

. _ _ _ _ _ _ _ _ _ _ _ _UINavigationBarMFMailComposerViewControllerMFMessageComposeViewControllerUIActivityViewController

使用 UIActivityViewController,点击MessageMail

使用 UIActivityViewController

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

默认蓝色

为了改变这一点,在AppDelegate.m类中的didFinishLaunchingWithOptions方法中,插入以下行:

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

这导致:

改成白色

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

[UIColor purpleColor];

变成紫色

[UIColor greenColor];

改为绿色

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

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

测试时它不起作用:

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

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

于 2014-04-12T19:34:07.333 回答
25

UIActivityViewController 中的条形颜色和状态栏颜色。斯威夫特 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
    }
}
于 2016-10-07T21:21:24.540 回答
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();
        }
    }];
}

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

于 2014-08-27T15:22:26.933 回答
4

对于斯威夫特:

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

于 2015-02-17T10:31:28.613 回答
4

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

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
    }

}
于 2017-11-01T22:54:14.323 回答
3

这似乎是 iOS 7 的一个错误。我在网上看到了其他关于此的报告。它似乎也没有在 iOS 7.1 中得到修复。

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

于 2014-03-27T12:37:56.183 回答
3

我的应用程序遇到了同样的问题,由于外观代理,tintColor属性到处都是白色的。UINavigationBar产生的效果是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,但您可以[[UIBarButtonItem appearance] setTintColor:]在 iOS 6 中使用(参见 Kevin van Mierlo 的回答)

于 2014-05-20T14:44:17.940 回答
1

试试这个代码可能对你有帮助

[[mailComposer navigationBar] setTintColor:[UIColor blackColor]];
于 2013-12-02T10:38:56.837 回答
1

好吧,我们不能改变苹果代码中的 UI 的方式是有原因的。主要是因为它是苹果的。它们不允许您以任何方式编辑 MFMailComposerViewController 中的 UI 外观。如果有办法,那么我对此一无所知,但我从未见过任何方法。MFMailComposeViewController 不支持外观属性,因为它是在 iOS 3.0 中创建的,并且外观直到 iOS 5.0 才成为一个东西

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

希望这可以帮助!

于 2013-11-15T15:33:13.570 回答
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]];
于 2013-11-21T12:19:22.143 回答
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 上运行良好,没有在新版本上尝试

于 2014-08-10T07:31:37.467 回答
1

我无法让亚历克斯的解决方案起作用,但是我设法得到了 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]];

谢谢帕尤!

于 2014-07-09T01:10:06.157 回答
0

对于 ios7 我认为你应该通过这段代码

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

如果它也不起作用,请尝试 Internet 上提供的 Mail Compose View Controller 苹果文档。

于 2013-12-27T18:53:03.713 回答
0

我对此有很大的麻烦,尤其是当MFMailComposeViewController/MFMessageViewController本身由 . 显示时UIActivityViewController

在https://github.com/rentzsch/jrswizzle的帮助下,我求助于使用方法 swizzling on viewDidAppear/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,但我很确定这是有原因的......)。

于 2015-02-18T14:58:18.887 回答
0

在呈现邮件编写器之前,请像这样插入这一行:

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

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

[self presentViewController:mailComposer animated:YES completion:^{[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];}];
于 2013-12-29T16:30:53.000 回答
0

我在 iOS 9 和 10 中尝试了许多不同的方法,但这是唯一有效的方法。请注意,我在导航栏后面也有一个背景图像:

[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;
于 2016-09-09T04:15:52.817 回答
0

Swift中,在iOS9上,设置

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

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

于 2016-07-18T12:41:49.527 回答
0

您可以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)
于 2018-09-12T13:38:55.530 回答
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)
于 2016-04-13T14:16:06.530 回答
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
}

然后在我UIActivityViewControllercompletionWithItemsHandler我包括:

[[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% 可靠的,但可以与我尝试过的所有扩展一起使用。

于 2019-05-14T16:17:44.873 回答