Невозможно установить цвет текста кнопок "Отправить" и "Отмена" в почтовом композиторе, если он представлен в UIActivityViewController в iOS7
Я использую 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
Удалось изменить цвет текста кнопок Отправить и Отмена, которые находятся на UINavigationBar
в MFMailComposerViewController
(оба Отправить и Отмена) и MFMessageComposeViewController
(только Отмена), если они представлены из UIActivityViewController
.
Используя UIActivityViewController, нажмите на Message
или Mail
:
![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. Также выбрано из Общего → Цель развертывания → 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, я бы хотел знать.:)
Ответ 2
Цвет оттенка штриха и цвет строки состояния в 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
}
}
Ответ 3
Вот что работает на 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();
}
}];
}
Это приведет к белым кнопкам и белой строке состояния.
Ответ 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
для изменения текста строки состояния цвет)
Ответ 5
Это, похоже, ошибка с iOS 7. Я видел другие отчеты об этом в Интернете. Он также не исправляется в iOS 7.1.
Чтобы быть конкретным, независимо от того, что вы делаете, вы не можете устанавливать цвета оттенков на панели навигации для диалогов, показанных с помощью UIActivityViewController.
Ответ 6
У меня была та же проблема с моим приложением, где свойство 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 (cf Kevin van Mierlo)
Ответ 7
Я исправил свою проблему путем подкласса 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
}
}
Ответ 8
Ну, есть причины, почему мы не можем изменить способ, которым пользовательский интерфейс в коде яблока является таким, каким он есть. В основном потому, что это яблоко. Они не позволяют редактировать способ отображения пользовательского интерфейса в MFMailComposerViewController. Если есть способ, то я понятия не имею, но я никогда не видел никакого способа сделать это. MFMailComposeViewController не поддерживает атрибут внешнего вида, поскольку он был создан в iOS 3.0, и внешний вид не стал чем-то, пока iOS 5.0
Вот ссылка на документацию Apple MFMailComposeViewController: MFMailComposeViewController
Надеюсь, это поможет!
Ответ 9
Если вы хотите установить цвет кнопок отмены и отправки в 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]];
Ответ 10
Попробуйте этот код, возможно, это поможет вам
[[mailComposer navigationBar] setTintColor:[UIColor blackColor]];
Ответ 11
Я не смог заставить решение 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!
Ответ 12
Это сработало для меня:
в 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, не пробовал более новые версии
Ответ 13
Вы можете настроить свой 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)
Ответ 14
Для ios7 я думаю, что вы должны пройти этот код
[[UINavigationBar appearance] setTintColor:[UIColor redColor]];
Если он также не работает, попробуйте загрузить документацию Apple Mail Compose View Controller в Интернете.
Ответ 15
Перед представлением почтового композитора вставьте эту строку следующим образом:
[mailComposer.navigationBar setTintColor:[UIColor whiteColor]];
[self presentViewController:mailComposer animated:YES completion:nil];
Несмотря на то, что я установил стиль строки в приложении, завершил запуск, мне также нужно было установить его снова в блоке завершения следующим образом:
[self presentViewController:mailComposer animated:YES completion:^{[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];}];
Ответ 16
У меня были огромные проблемы с этим, особенно когда MFMailComposeViewController
/MFMessageViewController
сами отображаются UIActivityViewController
.
Я применил метод swizzling на 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
(Должен признать, я не могу вспомнить, почему я нестандартно выглядел как в init
, так и viewWillAppear
, но я уверен, что была причина...).
Ответ 17
В 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)
Ответ 18
В Swift, на iOS9, установите
UINavigationBar.appearance().barTintColor = UIColor.greenColor() // eg
UINavigationBar.appearance().translucent = false
перед представлением контроллера вида активности помогло.
Ответ 19
Я пробовал много разных методов в 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;
Ответ 20
Я не нашел механизм, который мне понравился, поэтому за то, что он стоит здесь, мой. Частично проблема заключается в том, что в более поздних версиях 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 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 custom nav bar background color
Не имеет отношения к конкретной проблеме, но если у вас нет UIActivityItemSource
вам нужно сделать что-то вроде этого:
NSArray *[email protected][self]; //And set self to be a UIActivityItemSource
UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:activities applicationActivities:nil];
Я уверен, что это не на 100% надежно, но работало со всеми расширениями, которые я пробовал.