web-dev-qa-db-fra.com

Impossible de définir la couleur du texte des boutons Envoyer et Annuler dans le courrier composer lorsqu'il est présenté à partir de UIActivityViewController dans iOS7

J'utilise UIActivityViewController pour partager des éléments dans iOS7. Lorsque je tape sur l'option Courrier, le compositeur de messages apparaît, mais les boutons Annuler et Envoyer de la barre de navigation et de la barre de navigation elle-même sont bleus, ce qui rend la lecture très difficile, je souhaite donc changer leur couleur. Cela fonctionne dans iOS6 mais pas dans iOS7.

J'ai essayé

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

qui fonctionne dans iOS6, et j'ai essayé

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

ce qui fait que la couleur clignote en rouge la première fois que l'application est exécutée avant de revenir immédiatement à la couleur bleue.

67
Jonathan Shih

Géré pour changer la couleur du texte des boutons Envoyer et Annuler, qui se trouvent sur les UINavigationBar dans les MFMailComposerViewController (les deux Envoyer et Annuler) et MFMessageComposeViewController (uniquement Annuler), lorsqu'ils sont présentés à partir de UIActivityViewController.

À l'aide d'un UIActivityViewController, appuyez sur Messageou Mail:

Using an UIActivityViewController

Vous remarquerez que la couleur de texte par défaut des boutons Envoyer et Annuler est bleue:

Default blue colors

Pour changer cela, dans le AppDelegate.m classe, dans la méthode didFinishLaunchingWithOptions, insérez la ligne suivante:

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

Il en résulte:

Changed to white

Vous pouvez également utiliser d'autres couleurs, par exemple:

[UIColor purpleColor];

Change to purple

[UIColor greenColor];

Changed to green

Comment ai-je testé cela? J'ai remarqué que cette solution fonctionne pour les éléments suivants:

  • avec Xcode 5.1, dans le simulateur iOS 7.1, création en tant que SDK iOS de base 7.1 (peut être choisi en sélectionnant le fichier de projet -> Paramètres de construction -> SDK de base. Aussi, sélectionné dans Général -> Cible de déploiement -> 7.1)
  • avec Xcode 5.1, sur un iPhone 4, construit comme SDK iOS de base 7.0 (peut être choisi en sélectionnant le fichier de projet -> Paramètres de construction -> SDK de base. Aussi, sélectionné parmi Général -> Cible de déploiement -> 7.0)
  • avec Xcode 5.1, sur un iPhone 4, construit comme SDK iOS de base 7.1 (peut être choisi en sélectionnant le fichier de projet -> Paramètres de construction -> SDK de base. Aussi, sélectionné parmi Général -> Cible de déploiement -> 7.1)

Cela n'a pas fonctionné lors des tests avec:

  • avec Xcode 5.1, dans le simulateur iOS 7.0, création en tant que SDK iOS de base 7.0 (peut être choisi en sélectionnant le fichier de projet -> Paramètres de construction -> SDK de base. En outre, sélectionné dans Général -> Cible de déploiement -> 7.0)

Par conséquent, il devrait être sûr à utiliser, car je pense que le comportement sur l'appareil réel importe plus que le comportement dans le simulateur iOS. Si quelqu'un sait pourquoi cela ne fonctionne pas dans le simulateur iOS 7.0, je voudrais savoir. :)

76
Alex

Couleur de teinte de la barre et couleur de la barre d'état dans 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
    }
}
25
mazorati

Voici ce qui fonctionne sur iOS 7.1 à partir d'aujourd'hui.

Sous-classe UIActivityViewController et remplacez la méthode suivante:

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

Cela rendra les boutons blancs et la barre d'état blanche.

6
Maciej Swic

Pour Swift:

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

Cela changera Envoyer & Annuler la couleur du bouton en Blanc (testé sur iOS 7,8) mais je ne parviens toujours pas à rendre la couleur du texte de la barre d'état blanche (bien que je n'ai pas essayé cette solution de sous-classe UIActivityViewController pour changer la couleur du texte de la barre d'état)

4
Aks

J'ai eu le même problème avec mon application où la propriété tintColor de UINavigationBar est partout blanche grâce au proxy d'apparence. L'effet résultant est que UIBarButtonItem du courrier composer view controller navigationBar n'était pas visible (boutons blancs sur une barre de navigation blanche).

J'ai cet appel dans mon application:didFinishLaunchingWithOptions: méthode:

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

Comme il est impossible (pour l'instant?) D'accéder au UINavigationBar du mail composer contrôleur de vue dans le UIActivityViewController, j'ai fait la solution de contournement suivante qui est inspirée de la réponse d'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: ce code est destiné à iOS 7, mais vous pouvez utiliser [[UIBarButtonItem appearance] setTintColor:] dans iOS 6 (cf. la réponse de Kevin van Mierlo)

3
paillou

Cela semble être un bug avec iOS 7. J'ai vu d'autres rapports à ce sujet en ligne. Il ne semble pas non plus être corrigé dans iOS 7.1.

Pour être précis, peu importe ce que vous faites, vous ne pouvez pas définir de couleurs de teinte dans les barres de navigation pour les boîtes de dialogue affichées à partir de UIActivityViewController.

3

J'ai résolu mon problème en sous-classant UIActivityViewController comme ceci. 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
user3700746

Cela a fonctionné pour moi: dans AppDelegate.m dans la fonction:

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

J'ai entré le code suivant:

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

Cela fonctionne très bien sur iOS7 + iOS8, n'a pas essayé sur les versions plus récentes

1
Eliktz

Si vous souhaitez définir la couleur des boutons d'annulation et d'envoi dans iOS 7, vous devez utiliser ceci:

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

Dans iOS 6, ce sont en effet ceux-ci et vous devez également laisser cela dans votre 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
Kevin van Mierlo

Eh bien, il y a des raisons pour lesquelles nous ne pouvons pas changer la façon dont l'interface utilisateur dans le code d'Apple est la même. Principalement parce que c'est Apple. Ils ne vous permettent pas de modifier l'apparence de l'interface utilisateur dans MFMailComposerViewController. S'il y a un moyen, alors je n'en ai aucune idée, mais je n'ai jamais vu de moyen de le faire. MFMailComposeViewController ne prend pas en charge l'attribut d'apparence tel qu'il a été créé dans iOS 3.0, et l'apparence n'est devenue rien avant iOS 5.0

Voici un lien vers le MFMailComposeViewController Apple: MFMailComposeViewController

J'espère que cela t'aides!

1
user2277872

Essayez ce code car il vous aidera

[[mailComposer navigationBar] setTintColor:[UIColor blackColor]];
1
Pradhyuman sinh

Je n'ai pas réussi à faire fonctionner la solution d'Alex, mais j'ai réussi à obtenir une variation de la réponse de Paillou au travail même si j'ai dû définir à la fois le barTintColor et le titleTextAttributes dans ma 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]];

Merci Paillou!

1
staticnz

Vous pouvez définir votre appearance avant de présenter UIActivityViewController. Ajoutez la réinitialisation de l'apparence à completionWithItemsHandler de votre activity VC:

setNavBarAppearance()

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

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

Le seul problème, c'est que si l'activité est comme l'envoi de courrier, elle est en plein écran. Votre apparence ne sera pas appliquée aux vues visibles actuelles. Un peu de hacks pour le résoudre:

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
Vlad Pulichev

J'ai essayé de nombreuses méthodes différentes dans iOS 9 et 10, mais c'est la seule qui a fonctionné. Notez que j'ai également une image d'arrière-plan derrière la barre de navigation:

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

Je n'ai pas trouvé de mécanisme que j'aimais, alors pour ce que ça vaut, voici le mien. Une partie du problème est que les versions ultérieures d'iOS ajoutent la possibilité pour les applications d'ajouter des extensions de partage et d'action à l'échelle du système. Ces éléments tiers semblent être codés de toutes sortes de façons. Certains héritent du style de barre de navigation de l'application, certains utilisent le leur et certains semblent supposer une barre de navigation blanche (mais héritent en fait de l'application).

Ceci est testé sur iOS 12.2.

Je crée un UIActivityItemSource, auquel j'ai:

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

Puis dans mon UIActivityViewControllercompletionWithItemsHandler j'inclus:

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

Sans rapport avec le problème spécifique, mais si vous ne disposez pas actuellement d'un UIActivityItemSource, vous devez faire quelque chose comme ceci:

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

Je suis sûr que ce n'est pas fiable à 100%, mais a fonctionné avec toutes les extensions que j'ai essayées.

0
Mitch Cohen

Pour ios7, je pense que vous devriez passer par ce code

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

Si cela ne fonctionne pas non plus, essayez Mail Compose View Controller Apple disponible sur Internet.

0
santosh

Dans Swift j'ai fait une extension pour UIViewController:

extension UIViewController {

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

Lorsque je dois présenter un UIActivityViewController, j'appelle:

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

J'ai eu d'énormes problèmes avec cela, surtout lorsque MFMailComposeViewController/MFMessageViewController sont eux-mêmes affichés par UIActivityViewController.

J'ai recouru à l'utilisation de la méthode swizzling sur viewDidAppear/viewDidDisappear pour annuler puis refaire la personnalisation des couleurs et des polices de mon application, avec l'aide de 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

(Je dois admettre que je ne me souviens pas pourquoi j'ai des apparences non personnalisées à la fois dans init et viewWillAppear, mais je suis assez sûr qu'il y avait une raison ...).

0
jawj

Dans Swift, le iOS9, réglage

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

avant de présenter le contrôleur de vue d'activité a fait l'affaire pour moi.

0
Phlippie Bosman

Avant de présenter le mail composer insérez cette ligne comme ceci:

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

Même si j'ai défini le style de la barre d'état dans l'application, j'ai terminé le lancement, je devais également le définir à nouveau dans le bloc d'achèvement comme ceci:

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