Police personnalisée UIAlertController, taille, couleur


118

J'utilise le nouveau UIAlertController pour afficher les alertes. J'ai ce code:

// nil titles break alert interface on iOS 8.0, so we'll be using empty strings
UIAlertController *alert = [UIAlertController alertControllerWithTitle: title == nil ? @"": title message: message preferredStyle: UIAlertControllerStyleAlert];


UIAlertAction *defaultAction = [UIAlertAction actionWithTitle: cancelButtonTitle style: UIAlertActionStyleCancel handler: nil];

[alert addAction: defaultAction];

UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
[rootViewController presentViewController:alert animated:YES completion:nil];

Maintenant, je veux changer le titre et la police du message, la couleur, la taille, etc. Quelle est la meilleure façon de procéder?

Edit: je devrais insérer le code entier. J'ai créé une catégorie pour UIView que je pourrais afficher la bonne alerte pour la version iOS.

@implementation UIView (AlertCompatibility)

+( void )showSimpleAlertWithTitle:( NSString * )title
                          message:( NSString * )message
                cancelButtonTitle:( NSString * )cancelButtonTitle
{
    float iOSVersion = [[UIDevice currentDevice].systemVersion floatValue];
    if (iOSVersion < 8.0f)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle: title
                                                        message: message
                                                       delegate: nil
                                              cancelButtonTitle: cancelButtonTitle
                                              otherButtonTitles: nil];
        [alert show];
    }
    else
    {
        // nil titles break alert interface on iOS 8.0, so we'll be using empty strings
        UIAlertController *alert = [UIAlertController alertControllerWithTitle: title == nil ? @"": title
                                                                       message: message
                                                                preferredStyle: UIAlertControllerStyleAlert];


        UIAlertAction *defaultAction = [UIAlertAction actionWithTitle: cancelButtonTitle
                                                                style: UIAlertActionStyleCancel
                                                              handler: nil];

        [alert addAction: defaultAction];

        UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
        [rootViewController presentViewController:alert animated:YES completion:nil];
    }
}

2
DISCLAIMER:À tous ceux qui lisent les réponses ci-dessous. Apple rejettera vos applications. Si vous avez tendance à utiliser des API privées. Et dans les réponses ci-dessous C'EST CE QUI SE PASSE ..
Yash Bedi

Réponses:


98

Je ne sais pas si cela va à l'encontre des API / propriétés privées, mais l'utilisation de KVC fonctionne pour moi sur ios8

UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Dont care what goes here, since we're about to change below" message:@"" preferredStyle:UIAlertControllerStyleActionSheet];
NSMutableAttributedString *hogan = [[NSMutableAttributedString alloc] initWithString:@"Presenting the great... Hulk Hogan!"];
[hogan addAttribute:NSFontAttributeName
              value:[UIFont systemFontOfSize:50.0]
              range:NSMakeRange(24, 11)];
[alertVC setValue:hogan forKey:@"attributedTitle"];



UIAlertAction *button = [UIAlertAction actionWithTitle:@"Label text" 
                                        style:UIAlertActionStyleDefault
                                        handler:^(UIAlertAction *action){
                                                    //add code to make something happen once tapped
}];
UIImage *accessoryImage = [UIImage imageNamed:@"someImage"];
[button setValue:accessoryImage forKey:@"image"];

Pour mémoire, il est également possible de modifier la police de l'action d'alerte, en utilisant ces API privées. Encore une fois, votre application peut être rejetée, je n'ai pas encore essayé de soumettre un tel code.

let alert = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)

let action = UIAlertAction(title: "Some title", style: .Default, handler: nil)
let attributedText = NSMutableAttributedString(string: "Some title")

let range = NSRange(location: 0, length: attributedText.length)
attributedText.addAttribute(NSKernAttributeName, value: 1.5, range: range)
attributedText.addAttribute(NSFontAttributeName, value: UIFont(name: "ProximaNova-Semibold", size: 20.0)!, range: range)

alert.addAction(action)

presentViewController(alert, animated: true, completion: nil)

// this has to be set after presenting the alert, otherwise the internal property __representer is nil
guard let label = action.valueForKey("__representer")?.valueForKey("label") as? UILabel else { return }
label.attributedText = attributedText

Pour Swift 4.2 dans XCode 10 et plus, les 2 dernières lignes sont maintenant:

guard let label = (action!.value(forKey: "__representer")as? NSObject)?.value(forKey: "label") as? UILabel else { return }
        label.attributedText = attributedText

6
Ça marche. attributedTitlepour le titre et attributedMessagepour le message. Je ne sais pas si c'est la meilleure solution mais pour l'instant c'est assez bien pour moi.
Libor Zapletal

2
ce que toute personnalisation que nous pouvons ajouter sur les boutons UIAlertController ??
Aanchal Chaurasia

1
Merci! J'ai une petite question - on pourrait utiliser des polices et des couleurs personnalisées avec la vignette d'attribut et le message UIAlertController. Comment faire de même avec UIAlertAction?
p0lAris

72
J'espère qu'aucun de vous n'envisage de le publier sur l'App Store car il utilise des API privées. Sérieusement, je n'ai aucune idée de pourquoi ces réponses sont acceptées sur Stackoverflow alors qu'elles ne sont pas vraiment des «réponses». Ce sont des hacks que vous pouvez ou non vous permettre de publier dans le magasin d'applications.
TheCodingArt

3
En cas de publication de l'application sur l'App Store, certaines des utilisations privées de l'API sont autorisées par Apple, mais il ne doit pas utiliser les API qui peuvent nuire ou affecter le système / la confidentialité de l'utilisateur. Donc, probablement cette réponse peut être acceptée par de nombreuses personnes uniquement à cause de cela. Et cela n'affectera probablement pas l'App Store. Une personne qui a utilisé ceci peut-elle confirmer que son application n'est pas rejetée?
Mehul Thakkar

67

Vous pouvez modifier la couleur du bouton en appliquant une couleur de teinte à un UIAlertController.

Sur iOS 9, si la couleur de teinte de la fenêtre a été définie sur une couleur personnalisée, vous devez appliquer la couleur de teinte juste après avoir présenté l'alerte. Sinon, la couleur de teinte sera réinitialisée à votre couleur de teinte de fenêtre personnalisée.

// In your AppDelegate for example:
window?.tintColor = UIColor.redColor()

// Elsewhere in the App:
let alertVC = UIAlertController(title: "Title", message: "message", preferredStyle: .Alert)
alertVC.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
alertVC.addAction(UIAlertAction(title: "Ok", style: .Default, handler: nil))

// Works on iOS 8, but not on iOS 9
// On iOS 9 the button color will be red
alertVC.view.tintColor = UIColor.greenColor()

self.presentViewController(alert, animated: true, completion: nil)

// Necessary to apply tint on iOS 9
alertVC.view.tintColor = UIColor.greenColor()

20
Pour clarifier, définir le tintColor après la présentation du contrôleur fonctionne à la fois sur iOS 8 et 9, il n'est donc pas nécessaire de le définir deux fois.
arlomedia le

Merci d'avoir ajouté une réponse Swift et une solution de contournement pour ce problème dans iOS 9.
peacetype

3
Lorsque je tape et fais glisser mon doigt vers le bas, il revient à la couleur par défaut. Une idée?
msmq

C'est vraiment la seule réponse décente ici.
TheCodingArt

47

Vous pouvez changer la couleur du texte du bouton en utilisant ce code:

alertC.view.tintColor = your color;

Peut-être que cela vous aidera.


@esilver avez-vous réussi à trouver une solution qui fonctionne avec iOS9?
Ash

1
Je n'ai pas. J'ai créé un rapport de bogue avec Apple, # 22391695.
esilver

1
Plus d'informations à ce sujet. Il semble que lorsque vous faites défiler une longue liste d'éléments, celui que vous touchez pour faire défiler devient bleu ...
Bejil

3
Rien de tout cela ne fonctionne sur UIAlertController dans iOS9 et 9.1 .. Je ne sais pas ce que les gars d'Apple sont en place ... Besoin de changer manuellement la teinte de la fenêtre chaque fois qu'un contrôleur d'alerte est appelé et de le changer dans le gestionnaire.
Akhilesh Sharma

Il fonctionne avec iOS 9.3, sauf si vous retouchez à l'extérieur: revient au bleu du système
Rémi Belzanti

35

Dans Xcode 8 Swift 3.0

@IBAction func touchUpInside(_ sender: UIButton) {

    let alertController = UIAlertController(title: "", message: "", preferredStyle: .alert)

    //to change font of title and message.
    let titleFont = [NSFontAttributeName: UIFont(name: "ArialHebrew-Bold", size: 18.0)!]
    let messageFont = [NSFontAttributeName: UIFont(name: "Avenir-Roman", size: 12.0)!]

    let titleAttrString = NSMutableAttributedString(string: "Title Here", attributes: titleFont)
    let messageAttrString = NSMutableAttributedString(string: "Message Here", attributes: messageFont)

    alertController.setValue(titleAttrString, forKey: "attributedTitle")
    alertController.setValue(messageAttrString, forKey: "attributedMessage")

    let action1 = UIAlertAction(title: "Action 1", style: .default) { (action) in
        print("\(action.title)")
    }

    let action2 = UIAlertAction(title: "Action 2", style: .default) { (action) in
        print("\(action.title)")
    }

    let action3 = UIAlertAction(title: "Action 3", style: .default) { (action) in
        print("\(action.title)")
    }

    let okAction = UIAlertAction(title: "Ok", style: .default) { (action) in
        print("\(action.title)")
    }

    alertController.addAction(action1)
    alertController.addAction(action2)
    alertController.addAction(action3)
    alertController.addAction(okAction)

    alertController.view.tintColor = UIColor.blue
    alertController.view.backgroundColor = UIColor.black
    alertController.view.layer.cornerRadius = 40

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

}

Production

Police, taille et couleur personnalisées UIAlertController


Désolé mon frère, c'est le démarrage. Si nécessaire dans la fonctionnalité, je vous informerai ...
iOS

24

Une traduction rapide de la réponse @ dupuis2387. Élaboration de la syntaxe pour définir la UIAlertControllercouleur et la police du titre via KVC à l'aide de la attributedTitleclé.

let message = "Some message goes here."
let alertController = UIAlertController(
    title: "", // This gets overridden below.
    message: message,
    preferredStyle: .Alert
)
let okAction = UIAlertAction(title: "OK", style: .Cancel) { _ -> Void in
}
alertController.addAction(okAction)

let fontAwesomeHeart = "\u{f004}"
let fontAwesomeFont = UIFont(name: "FontAwesome", size: 17)!
let customTitle:NSString = "I \(fontAwesomeHeart) Swift" // Use NSString, which lets you call rangeOfString()
let systemBoldAttributes:[String : AnyObject] = [ 
    // setting the attributed title wipes out the default bold font,
    // so we need to reconstruct it.
    NSFontAttributeName : UIFont.boldSystemFontOfSize(17)
]
let attributedString = NSMutableAttributedString(string: customTitle as String, attributes:systemBoldAttributes)
let fontAwesomeAttributes = [
    NSFontAttributeName: fontAwesomeFont,
    NSForegroundColorAttributeName : UIColor.redColor()
]
let matchRange = customTitle.rangeOfString(fontAwesomeHeart)
attributedString.addAttributes(fontAwesomeAttributes, range: matchRange)
alertController.setValue(attributedString, forKey: "attributedTitle")

self.presentViewController(alertController, animated: true, completion: nil)

entrez la description de l'image ici


3
Et le bouton "OK"? Pouvons-nous le personnaliser?
Hassan Taleb

@HassanTaleb Je n'ai pas trouvé un excellent moyen de personnaliser le bouton. Vous pouvez régler le tintColorsur viewou via appearanceWhenContainedIn, mais la teinte disparaît dès que vous la touchez. Toujours à la recherche de réponses.
Robert Chen

@AbdulMomen عبدالمؤمن Quel message d'erreur voyez-vous? L'extrait de code suppose que FontAwesome est déjà configuré.
Robert Chen

1
@RobertChen pour résoudre le problème, il suffit de mettre la teinte après:, self.presentViewController(alertController, animated: true, completion: nil)pouvons-nous changer la police du bouton "OK"?
Hassan Taleb

4
N'est-ce pas considéré comme une API privée?
Jinghan Wang

13

Utilisez le UIAppearanceprotocole. Exemple de définition d'une police - créez une catégorie à étendre UILabel:

@interface UILabel (FontAppearance)
@property (nonatomic, copy) UIFont * appearanceFont UI_APPEARANCE_SELECTOR;
@end


@implementation UILabel (FontAppearance)

-(void)setAppearanceFont:(UIFont *)font {
    if (font)
        [self setFont:font];
}

-(UIFont *)appearanceFont {
    return self.font;
}

@end

Et son utilisation:

UILabel * appearanceLabel = [UILabel appearanceWhenContainedIn:UIAlertController.class, nil];
[appearanceLabel setAppearanceFont:[UIFont boldSystemFontOfSize:10]]; //for example

Testé et travaillé avec style UIAlertControllerStyleActionSheet, mais je suppose que cela fonctionnera avecUIAlertControllerStyleAlert aussi.

PS Mieux vaut vérifier la disponibilité des classes au lieu de la version iOS:

if ([UIAlertController class]) {
    // UIAlertController code (iOS 8)
} else {
    // UIAlertView code (pre iOS 8)
}

Cela fonctionne mais de cette façon je ne peux pas avoir une taille différente pour le message et pour le titre.
Libor Zapletal

Cela fonctionne, mais quand une action est cliquée, la police revient à sa taille d'origine? Cela vous arrive-t-il?
Larry

J'ai le même problème @Larry et je n'ai pas trouvé de moyen de le résoudre ... n'est-ce pas?
alasker le

12

Utilisez le UIAppearanceprotocole. Faites plus de hacks avec appearanceFontpour changer la police pourUIAlertAction .

Créer une catégorie pour UILabel

UILabel + FontAppearance.h

@interface UILabel (FontAppearance)

@property (nonatomic, copy) UIFont * appearanceFont UI_APPEARANCE_SELECTOR;

@end

UILabel + FontAppearance.m

@implementation UILabel (FontAppearance)

- (void)setAppearanceFont:(UIFont *)font
{
    if (self.tag == 1001) {
        return;
    }

    BOOL isBold = (self.font.fontDescriptor.symbolicTraits & UIFontDescriptorTraitBold);
    const CGFloat* colors = CGColorGetComponents(self.textColor.CGColor);

    if (self.font.pointSize == 14) {
        // set font for UIAlertController title
        self.font = [UIFont systemFontOfSize:11];
    } else if (self.font.pointSize == 13) {
        // set font for UIAlertController message
        self.font = [UIFont systemFontOfSize:11];
    } else if (isBold) {
        // set font for UIAlertAction with UIAlertActionStyleCancel
        self.font = [UIFont systemFontOfSize:12];
    } else if ((*colors) == 1) {
        // set font for UIAlertAction with UIAlertActionStyleDestructive
        self.font = [UIFont systemFontOfSize:13];
    } else {
        // set font for UIAlertAction with UIAlertActionStyleDefault
        self.font = [UIFont systemFontOfSize:14];
    }
    self.tag = 1001;
}

- (UIFont *)appearanceFont
{
    return self.font;
}

@end

Usage:

ajouter

[[UILabel appearanceWhenContainedIn:UIAlertController.class, nil] setAppearanceFont:nil];

en AppDelegate.mpour le faire fonctionner pour tous UIAlertController.


Le titre dans iOS 8.3 est 13 pt et en gras, j'ai donc changé la condition enif (self.font.pointSize == 13 && isBold) {
Andrew Raphael

Vous avez mentionné la modification de la police pour UIAlertAction. Mais pour autant que je sache, UIAlertActionn'utilise pas de fichier UILabel. Il utilise un fichier NSString. github.com/nst/iOS-Runtime-Headers/blob/ ... Je ne sais pas comment vous pourriez personnaliser la police pour un fichierNSString .
peacetype

UIAlertAction n'est pas du tout une classe de vue. C'est une classe abstraite décrivant l'action. La vue elle-même est ensuite générée dans UIAlertController. Vous définissez donc l'apparence contenue dans UIAlertController.
mangerlahn

12

Swift 5 et 5.1 . Créez un fichier séparé et placez-y le code de personnalisation UIAlertController

import Foundation
import  UIKit

extension UIAlertController {

  //Set background color of UIAlertController
  func setBackgroudColor(color: UIColor) {
    if let bgView = self.view.subviews.first,
      let groupView = bgView.subviews.first,
      let contentView = groupView.subviews.first {
      contentView.backgroundColor = color
    }
  }

  //Set title font and title color
  func setTitle(font: UIFont?, color: UIColor?) {
    guard let title = self.title else { return }
    let attributeString = NSMutableAttributedString(string: title)//1
    if let titleFont = font {
      attributeString.addAttributes([NSAttributedString.Key.font : titleFont],//2
        range: NSMakeRange(0, title.utf8.count))
    }
    if let titleColor = color {
      attributeString.addAttributes([NSAttributedString.Key.foregroundColor : titleColor],//3
        range: NSMakeRange(0, title.utf8.count))
    }
    self.setValue(attributeString, forKey: "attributedTitle")//4
  }

  //Set message font and message color
  func setMessage(font: UIFont?, color: UIColor?) {
    guard let title = self.message else {
      return
    }
    let attributedString = NSMutableAttributedString(string: title)
    if let titleFont = font {
      attributedString.addAttributes([NSAttributedString.Key.font : titleFont], range: NSMakeRange(0, title.utf8.count))
    }
    if let titleColor = color {
      attributedString.addAttributes([NSAttributedString.Key.foregroundColor : titleColor], range: NSMakeRange(0, title.utf8.count))
    }
    self.setValue(attributedString, forKey: "attributedMessage")//4
  }

  //Set tint color of UIAlertController
  func setTint(color: UIColor) {
    self.view.tintColor = color
  }
}

Maintenant sur n'importe quelle action Afficher l'alerte

  func tapShowAlert(sender: UIButton) {
    let alertController = UIAlertController(title: "Alert!!", message: "This is custom alert message", preferredStyle: .alert)
    // Change font and color of title
    alertController.setTitle(font: UIFont.boldSystemFont(ofSize: 26), color: UIColor.yellow)
    // Change font and color of message
    alertController.setMessage(font: UIFont(name: "AvenirNextCondensed-HeavyItalic", size: 18), color: UIColor.red)
    // Change background color of UIAlertController
    alertController.setBackgroudColor(color: UIColor.black)
    let actnOk = UIAlertAction(title: "Ok", style: .default, handler: nil)
    let actnCancel = UIAlertAction(title: "Cancel", style: .default, handler: nil)
    alertController.addAction(actnOk)
    alertController.addAction(actnCancel)
    self.present(alertController, animated: true, completion: nil)
  }

Résultat

entrez la description de l'image ici


1
accédons-nous à des API privées ici.? avez-vous publié une application avec ces nombreuses propriétés d'alerte personnalisées?
Yash Bedi

@YashBedi utilise des API privées et Apple pourrait rejeter votre application pour une utilisation "API non publique". Non, je n'ai publié aucune application.
Gurjinder Singh

Ceci est mentionné sur le site des développeurs Apple -> Important La classe UIAlertController est destinée à être utilisée telle quelle et ne prend pas en charge le sous-classement. La hiérarchie des vues de cette classe est privée et ne doit pas être modifiée.
Gurjinder Singh

Got it Boss Merci.
Yash Bedi

@Darkglow Veuillez mentionner l'erreur. Je suis capable de construire avec succès le même code avec swift 5.1
Gurjinder Singh

10

Je l'utilise.

[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor blueColor]];

Ajoutez une ligne (AppDelegate) et fonctionne pour tous les UIAlertController.


3
Comme cela est désormais obsolète, utilisez [[UIView lookWhenContainedInInstancesOfClasses: @ [[UIAlertController class]]] setTintColor: newColor]; à la place
Peter Johnson

8

Swift 4

Exemple de police personnalisée sur le titre. Mêmes choses pour les autres composants tels que le message ou les actions.

    let titleAttributed = NSMutableAttributedString(
            string: Constant.Strings.cancelAbsence, 
            attributes: [NSAttributedStringKey.font:UIFont(name:"FONT_NAME",size: FONT_SIZE)]
    )

    let alertController = UIAlertController(
        title: "",
        message: "",
        preferredStyle: UIAlertControllerStyle.YOUR_STYLE
    )

    alertController.setValue(titleAttributed, forKey : "attributedTitle")
    present(alertController, animated: true, completion: nil)

5

Voici une extension pour Swift 4.1 et Xcode 9.4.1:

extension UIAlertController{

func addColorInTitleAndMessage(color:UIColor,titleFontSize:CGFloat = 18, messageFontSize:CGFloat = 13){

    let attributesTitle = [NSAttributedStringKey.foregroundColor: color, NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: titleFontSize)]
    let attributesMessage = [NSAttributedStringKey.foregroundColor: color, NSAttributedStringKey.font: UIFont.systemFont(ofSize: messageFontSize)]
    let attributedTitleText = NSAttributedString(string: self.title ?? "", attributes: attributesTitle)
    let attributedMessageText = NSAttributedString(string: self.message ?? "", attributes: attributesMessage)

    self.setValue(attributedTitleText, forKey: "attributedTitle")
    self.setValue(attributedMessageText, forKey: "attributedMessage")

}}

4

Je viens de terminer un remplacement pour UIAlertController. C'est la seule façon raisonnable de procéder, je pense:


Vieux

Voici ma méthode dans Swift qui regroupe beaucoup d'informations à partir des réponses ici

func changeAlert(alert: UIAlertController, backgroundColor: UIColor, textColor: UIColor, buttonColor: UIColor?) {
    let view = alert.view.firstSubview().firstSubview()
    view.backgroundColor = backgroundColor
    view.layer.cornerRadius = 10.0

    // set color to UILabel font
    setSubviewLabelsToTextColor(textColor, view: view)

    // set font to alert via KVC, otherwise it'll get overwritten
    let titleAttributed = NSMutableAttributedString(
        string: alert.title!,
        attributes: [NSFontAttributeName:UIFont.boldSystemFontOfSize(17)])
    alert.setValue(titleAttributed, forKey: "attributedTitle")


    let messageAttributed = NSMutableAttributedString(
        string: alert.message!,
        attributes: [NSFontAttributeName:UIFont.systemFontOfSize(13)])
    alert.setValue(messageAttributed, forKey: "attributedMessage")


    // set the buttons to non-blue, if we have buttons
    if let buttonColor = buttonColor {
        alert.view.tintColor = buttonColor
    }
}

func setSubviewLabelsToTextColor(textColor: UIColor, view:UIView) {
    for subview in view.subviews {
        if let label = subview as? UILabel {
            label.textColor = textColor
        } else {
            setSubviewLabelsToTextColor(textColor, view: subview)
        }
    }
}

Cela fonctionne parfaitement dans certaines situations, et dans d'autres, c'est un échec total (les couleurs de teinte ne s'affichent pas comme prévu).


4

Vous pouvez utiliser une bibliothèque externe telle que PMAlertController sans utiliser de solution de contournement, où vous pouvez remplacer le UIAlertController non personnalisable d'Apple par une alerte super personnalisable.

Compatible avec Xcode 8, Swift 3 et Objective-C

Exemple de PMAlertController


Fonctionnalités:

  • [x] Vue d'en-tête
  • [x] Image d'en-tête (facultatif)
  • [x] Titre
  • [x] Message de description
  • [x] Personnalisations: polices, couleurs, dimensions et plus
  • [x] 1, 2 boutons (horizontalement) ou 3+ boutons (verticalement)
  • [x] Fermeture lorsqu'un bouton est enfoncé
  • [x] Prise en charge des champs de texte
  • [x] Implémentation similaire à UIAlertController
  • [x] Cocoapodes
  • [x] Carthage
  • [x] Animation avec UIKit Dynamics
  • [x] Compatibilité Objective-C
  • [x] Prise en charge de Swift 2.3 et Swift 3

PMAlertController autorise-t-il le retour à la ligne lorsque le texte est long dans les boutons d'action?
zeeple

@zeeple considère que le bouton d'action est une sous-classe de UIButton. Quelque chose comme ça actionButton.titleLabel.lineBreakMode = NSLineBreakByWordWrappingfonctionne bien.
Paolo Musolino

3

Il y a un problème avec le réglage de la couleur de teinte sur la vue après la présentation; même si vous le faites dans le bloc de complétion de presentViewController: animated: completion :, cela provoque un effet de scintillement sur la couleur des titres des boutons. C'est bâclé, non professionnel et totalement inacceptable.

D'autres solutions présentées dépendent du fait que la hiérarchie des vues reste statique, ce qu'Apple déteste faire. Attendez-vous à ce que ces solutions échouent dans les futures versions d'iOS.

Le seul moyen sûr de résoudre ce problème et de le faire partout, consiste à ajouter une catégorie à UIAlertController et à faire basculer viewWillAppear.

L'en-tête:

//
//  UIAlertController+iOS9TintFix.h
//
//  Created by Flor, Daniel J on 11/2/15.
//

#import <UIKit/UIKit.h>

@interface UIAlertController (iOS9TintFix)

+ (void)tintFix;

- (void)swizzledViewWillAppear:(BOOL)animated;

@end

La mise en oeuvre:

//
//  UIAlertController+iOS9TintFix.m
//
//  Created by Flor, Daniel J on 11/2/15.
//

#import "UIAlertController+iOS9TintFix.h"
#import <objc/runtime.h>

@implementation UIAlertController (iOS9TintFix)

+ (void)tintFix {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Method method  = class_getInstanceMethod(self, @selector(viewWillAppear:));
        Method swizzle = class_getInstanceMethod(self, @selector(swizzledViewWillAppear:));
        method_exchangeImplementations(method, swizzle);});
}

- (void)swizzledViewWillAppear:(BOOL)animated {
    [self swizzledViewWillAppear:animated];
    for (UIView *view in self.view.subviews) {
        if (view.tintColor == self.view.tintColor) {
            //only do those that match the main view, so we don't strip the red-tint from destructive buttons.
            self.view.tintColor = [UIColor colorWithRed:0.0 green:122.0/255.0 blue:1.0 alpha:1.0];
            [view setNeedsDisplay];
        }
    }
}

@end

Ajoutez un .pch (en-tête précompilé) à votre projet et incluez la catégorie:

#import "UIAlertController+iOS9TintFix.h"

Assurez-vous d'enregistrer correctement votre pch dans le projet et il inclura les méthodes de catégorie dans chaque classe qui utilise UIAlertController.

Ensuite, dans la méthode didFinishLaunchingWithOptions de vos délégués d'application, importez votre catégorie et appelez

[UIAlertController tintFix];

et il se propagera automatiquement à chaque instance de UIAlertController dans votre application, qu'elle soit lancée par votre code ou par quelqu'un d'autre.

Cette solution fonctionne à la fois pour iOS 8.X et iOS 9.X et n'a pas le scintillement de l'approche post-présentation du changement de teinte. Il est également totalement indépendant de la hiérarchie des vues des sous-vues de UIAlertController.

Bon piratage!


Cette solution fonctionne, principalement. Sur la rotation de l'appareil, cependant, les teintes reviennent à ce qu'elles étaient, avant le swizzling.
Dhiraj Gupta

Dhiraj, je viens de tester cela à nouveau dans une configuration de projet explicitement pour explorer vos résultats, et je ne suis pas d'accord. La teinte ne revient pas à la façon dont elle était lors de la rotation.
ObiDan

Fonctionnel vérifié sur xcode 6.4 et xcode 7.0. Exécution de simulateurs de toutes les variantes de 8.X et 9.0. Si demandé, je mettrai le projet sur github.
ObiDan

Eh bien, vous pourriez aller de l'avant et monter un projet, mais c'est ce que je voyais m'arriver. Cela ne fonctionnait pas non plus sur iPad. Sur la base de votre idée méthode swizzling, cependant, je suis en mesure de le faire fonctionner par swizzling viewDidLayoutSubviews, cependant.
Dhiraj Gupta

Si vous mettez en place un projet, alors je pourrais soumettre une pull request avec le swizzle viewDidLayoutSubviews, qui est ce que je viens d'utiliser et de soumettre dans la dernière version de mon application à l'App Store et vous pouvez y jeter un œil, peut-être?
Dhiraj Gupta

3

Veuillez trouver ceci catégorie. Je suis capable de changer la police et la couleur de UIAlertAction et UIAlertController.

Utilisation:

UILabel * appearanceLabel = [UILabel appearanceWhenContainedIn:UIAlertController.class, nil];
[appearanceLabel setAppearanceFont:yourDesireFont]];  

5
Veuillez coller le code ici ou utiliser un service qui ne nécessite pas de connexion.
Sulthan

3

Dans Swift 4.1 et Xcode 10

//Displaying alert with multiple actions and custom font ans size
let alert = UIAlertController(title: "", message: "", preferredStyle: .alert)

let titFont = [NSAttributedStringKey.font: UIFont(name: "ArialHebrew-Bold", size: 15.0)!]
let msgFont = [NSAttributedStringKey.font: UIFont(name: "Avenir-Roman", size: 13.0)!]

let titAttrString = NSMutableAttributedString(string: "Title Here", attributes: titFont)
let msgAttrString = NSMutableAttributedString(string: "Message Here", attributes: msgFont)

alert.setValue(titAttrString, forKey: "attributedTitle")
alert.setValue(msgAttrString, forKey: "attributedMessage")

let action1 = UIAlertAction(title: "Action 1", style: .default) { (action) in
    print("\(String(describing: action.title))")
}

let action2 = UIAlertAction(title: "Action 2", style: .default) { (action) in
    print("\(String(describing: action.title))")
}

let okAction = UIAlertAction(title: "Ok", style: .default) { (action) in
    print("\(String(describing: action.title))")
}
alert.addAction(action1)
alert.addAction(action2)
alert.addAction(okAction)

alert.view.tintColor = UIColor.blue
alert.view.layer.cornerRadius = 40
// //If required background colour 
// alert.view.backgroundColor = UIColor.white

DispatchQueue.main.async(execute: {
    self.present(alert, animated: true)
})

votre réponse nécessite une mise à jour, self.present(alertController, animated: true)ou self.present(alert, animated: true).
Yash Bedi

@Yash Bedi, merci d'avoir mis à jour ma réponse, veuillez la vérifier une fois.
iOS

2

Solution / Hack pour iOS9

    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Test Error" message:@"This is a test" preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        NSLog(@"Alert View Displayed");
 [[[[UIApplication sharedApplication] delegate] window] setTintColor:[UIColor whiteColor]];
    }];

    [alertController addAction:cancelAction];
    [[[[UIApplication sharedApplication] delegate] window] setTintColor:[UIColor blackColor]];
    [self presentViewController:alertController animated:YES completion:^{
        NSLog(@"View Controller Displayed");
    }];

J'ai essayé ça. Notez que vous rétablissez le paramètre de teinte de la fenêtre une fois que le contrôleur d'alerte est présenté. Je vois la couleur revenir à droite sur le contrôleur d'alerte. Je crois que le retour doit être effectué une fois qu'une action est activée.
Germán

Merci @ Germán pour l'avoir signalé .. Apporter les modifications au code. Je gère le retour dans AlertAction à partir de maintenant .. Mais oui, je suis d'accord que cela peut également être géré dans le gestionnaire dimiss
Akhilesh Sharma

1

Je travaille pour Urban Outfitters. Nous avons un pod open source URBNAlert, que nous avons utilisé dans toutes nos applications. Il est basé sur UIAlertController, mais est hautement personnalisable.

La source est ici: https://github.com/urbn/URBNAlert

Ou simplement installer par le pod en plaçant URBNAlert dans votre Podfile

Voici un exemple de code:

URBNAlertViewController *uac = [[URBNAlertViewController alloc] initWithTitle:@"The Title of my message can be up to 2 lines long. It wraps and centers." message:@"And the message that is a bunch of text. And the message that is a bunch of text. And the message that is a bunch of text."];

// You can customize style elements per alert as well. These will override the global style just for this alert.
uac.alertStyler.blurTintColor = [[UIColor orangeColor] colorWithAlphaComponent:0.4];
uac.alertStyler.backgroundColor = [UIColor orangeColor];
uac.alertStyler.textFieldEdgeInsets = UIEdgeInsetsMake(0.0, 15.0, 0.0, 15.0);
uac.alertStyler.titleColor = [UIColor purpleColor];
uac.alertStyler.titleFont = [UIFont fontWithName:@"Chalkduster" size:30];
uac.alertStyler.messageColor = [UIColor blackColor];
uac.alertStyler.alertMinWidth = @150;
uac.alertStyler.alertMaxWidth = @200;
// many more styling options available 

[uac addAction:[URBNAlertAction actionWithTitle:@"Ok" actionType:URBNAlertActionTypeNormal actionCompleted:^(URBNAlertAction *action) {
      // Do something
}]];

[uac addAction:[URBNAlertAction actionWithTitle:@"Cancel" actionType:URBNAlertActionTypeCancel actionCompleted:^(URBNAlertAction *action) {
      // Do something
}]];

[uac show];

Est-ce que cela prend en charge le style ActionSheet?
Danpe

@Danpe ce n'est pas le cas, c'est uniquement pour les alertes .. Cela étant dit .. si c'est quelque chose que vous désirez créer un problème sur le repo. C'est quelque chose dont nous avons déjà discuté pour ajouter un support
RyanG

1

Pour changer la couleur d'un bouton comme CANCEL en couleur rouge, vous pouvez utiliser cette propriété de style appelée UIAlertActionStyle.destructive:

let prompt = UIAlertController.init(title: "Reset Password", message: "Enter Your E-mail :", preferredStyle: .alert)
        let okAction = UIAlertAction.init(title: "Submit", style: .default) { (action) in
              //your code
}

let cancelAction = UIAlertAction.init(title: "Cancel", style: UIAlertActionStyle.destructive) { (action) in
                //your code
        }
        prompt.addTextField(configurationHandler: nil)
        prompt.addAction(okAction)
        prompt.addAction(cancelAction)
        present(prompt, animated: true, completion: nil);

1

Pour iOS 9.0 et supérieur, utilisez ce code dans le délégué d'application

[[UIView appearanceWhenContainedInInstancesOfClasses:@[[UIAlertController class]]] setTintColor:[UIColor redColor]];

1

Swift 5.0

let titleAttrString = NSMutableAttributedString(string: "This is a title", attributes: [NSAttributedString.Key.font: UIFont(name: "CustomFontName", size: 17) as Any])
let messageAttrString = NSMutableAttributedString(string: "This is a message", attributes: [NSAttributedString.Key.font: UIFont(name: "CustomFontName", size: 13) as Any])

alertController.setValue(titleAttrString, forKey: "attributedTitle")
alertController.setValue(messageAttrString, forKey: "attributedMessage")

0

Un peu maladroit, mais cela fonctionne pour moi en ce moment pour définir les couleurs d'arrière-plan et de texte. Je l'ai trouvé ici .

UIView * firstView = alertController.view.subviews.firstObject;
    UIView * nextView = firstView.subviews.firstObject;
    nextView.backgroundColor = [UIColor blackColor];

Cela fonctionne pour la couleur d'arrière-plan, mais cela ne change jamais la couleur de la teinte, c'est ce dont je suis un peu confus
Akhilesh Sharma

0

J'ai créé une méthode objective-C

-(void)customAlertTitle:(NSString*)title message:(NSString*)message{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:nil cancelButtonTitle:@"NO" otherButtonTitles:@"YES", nil];
UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 80)];

UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 270, 50)];
titleLabel.text = title;
titleLabel.font = [UIFont boldSystemFontOfSize:20];
titleLabel.numberOfLines = 2;
titleLabel.textColor = [UIColor redColor];
titleLabel.textAlignment = NSTextAlignmentCenter;

[subView addSubview:titleLabel];

UILabel *messageLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 30, 270, 50)];
messageLabel.text = message;
messageLabel.font = [UIFont systemFontOfSize:18];
messageLabel.numberOfLines = 2;
messageLabel.textColor = [UIColor redColor];
messageLabel.textAlignment = NSTextAlignmentCenter;

[subView addSubview:messageLabel];

[alertView setValue:subView forKey:@"accessoryView"];
[alertView show];
}

Le code fonctionne parfaitement sur Xcode 8.3.1. Vous pouvez personnaliser selon les besoins.


0

J'utilise juste ce genre de demande, apparemment et système, les détails sont légèrement différents, donc nous sommes ... OC a réalisé l'encapsulation de la fenêtre popup Alert and Sheet.

Souvent rencontrés dans le développement quotidien, il est nécessaire d'ajouter un chiffre à Alert ou de changer la couleur d'un bouton, comme la demande «simple», apporte aujourd'hui un et des composants système très similaires et peut pleinement répondre à la demande de composants d'emballage personnalisés.

Github: https://github.com/ReverseScale/RSCustomAlertView

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.