Benutzerdefinierte Schriftart, Größe und Farbe von UIAlertController

117

Ich verwende den neuen UIAlertController zum Anzeigen von Warnungen. Ich habe diesen 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];

Jetzt möchte ich Titel, Schriftart, Farbe, Größe usw. ändern. Was ist der beste Weg, dies zu tun?

Bearbeiten: Ich sollte ganzen Code einfügen. Ich habe eine Kategorie für UIView erstellt, in der die richtige Warnung für die iOS-Version angezeigt werden kann.

@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];
    }
}
Libor Zapletal
quelle
2
DISCLAIMER:An alle, die die folgenden Antworten lesen. Apple lehnt Ihre App (s) ab. Wenn Sie dazu neigen, private APIs zu verwenden. Und in den folgenden Antworten ist das, was passiert.
Yash Bedi

Antworten:

98

Ich bin mir nicht sicher, ob dies gegen private APIs / Eigenschaften verstößt, aber die Verwendung von KVC funktioniert für mich auf 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"];

Für den Datensatz ist es auch möglich, die Schriftart der Warnungsaktion mithilfe dieser privaten APIs zu ändern. Auch hier kann es sein, dass Ihre App abgelehnt wird. Ich habe noch nicht versucht, einen solchen Code einzureichen.

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

Für Swift 4.2 in XCode 10 und höher lauten die letzten beiden Zeilen jetzt:

guard let label = (action!.value(forKey: "__representer")as? NSObject)?.value(forKey: "label") as? UILabel else { return }
        label.attributedText = attributedText
dupuis2387
quelle
6
Es funktioniert. attributedTitlefür Titel und attributedMessagefür Nachricht. Ich bin mir nicht sicher, ob es die beste Lösung ist, aber im Moment ist es gut genug für mich.
Libor Zapletal
2
Welche Anpassungen können wir an den UIAlertController-Schaltflächen vornehmen?
Aanchal Chaurasia
1
Vielen Dank! Ich habe eine kleine Frage - man könnte benutzerdefinierte Schriftarten und Farben mit dem Attribut Kachel und Nachricht in verwenden UIAlertController. Wie kann man das auch machen UIAlertAction?
p0lAris
71
Ich hoffe, keiner von Ihnen plant, dies für den App Store freizugeben, da dieser private APIs verwendet. Im Ernst, ich habe keine Ahnung, warum diese Antworten jemals bei Stackoverflow akzeptiert werden, wenn sie nicht wirklich "Antworten" sind. Dies sind Hacks, die Sie möglicherweise mit der Veröffentlichung im Anwendungsspeicher nicht schaffen.
TheCodingArt
3
Für den Fall, dass eine App im App Store veröffentlicht wird, sind einige der privaten API-Verwendungen von Apple zulässig. Es sollten jedoch keine APIs verwendet werden, die das System / die Privatsphäre des Benutzers schädigen oder beeinträchtigen können. Wahrscheinlich wird diese Antwort nur deshalb von vielen Menschen akzeptiert. Und wahrscheinlich hat dies keine Auswirkungen auf den App Store. Kann jemand, der dies verwendet hat, bestätigen, dass seine App nicht abgelehnt wird?
Mehul Thakkar
66

Sie können die Tastenfarbe ändern, indem Sie einem UIAlertController eine Farbtonfarbe zuweisen.

Wenn unter iOS 9 die Fenstertönungsfarbe auf eine benutzerdefinierte Farbe eingestellt wurde, müssen Sie die Tönungsfarbe direkt nach dem Anzeigen der Warnung anwenden. Andernfalls wird die Farbtonfarbe auf Ihre benutzerdefinierte Fenstertönungsfarbe zurückgesetzt.

// 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()
Macucula
quelle
20
Zur Verdeutlichung funktioniert das Einstellen von tintColor nach der Präsentation des Controllers sowohl unter iOS 8 als auch unter 9, sodass es nicht erforderlich ist, es zweimal einzustellen.
Arlomedia
Vielen Dank, dass Sie eine
schnelle
3
Wenn ich auf meinen Finger tippe und ihn nach unten ziehe, wird wieder die Standardfarbe angezeigt. Irgendeine Idee?
msmq
Dies ist wirklich die einzige anständige Antwort hier.
TheCodingArt
46

Mit diesem Code können Sie die Farbe des Schaltflächentexts ändern:

alertC.view.tintColor = your color;

Vielleicht hilft dir das.

ChintaN -Maddy- Ramani
quelle
@esilver haben Sie es geschafft, eine Lösung zu finden, die mit iOS9 funktioniert?
Ash
1
Ich hab nicht. Ich habe mit Apple einen Fehlerbericht erstellt, # 22391695.
Silber
1
Weitere Informationen dazu. Es scheint, dass, wenn Sie in einer langen Liste Elemente scrollen, die, die Sie berühren, um zu scrollen, blau wird ...
Bejil
3
Nichts davon funktioniert mit UIAlertController in iOS9 und 9.1. Sie wissen nicht, was Apple-Leute vorhaben ... Sie müssen die Fenstertönung jedes Mal manuell ändern, wenn ein Alert-Controller aufgerufen wird, und sie im Handler wieder ändern.
Akhilesh Sharma
Es funktioniert mit iOS 9.3, es sei denn, Sie reparieren außerhalb: es kommt zurück zu System blau
Rémi Belzanti
35

In 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)

}

Ausgabe

Benutzerdefinierte Schriftart, Größe und Farbe von UIAlertController

Ashok R.
quelle
Sorry Bruder, das ist Start. Wenn in der Funktion erforderlich, werde ich Sie informieren ...
iOS
24

Eine schnelle Übersetzung der Antwort @ dupuis2387. Erarbeitete die Syntax, um die UIAlertControllerFarbe und Schriftart des Titels über KVC mit der attributedTitleTaste festzulegen .

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)

Geben Sie hier die Bildbeschreibung ein

Robert Chen
quelle
3
Was ist mit "OK"? Können wir es anpassen?
Hassan Taleb
@ HassanTaleb Ich habe keine großartige Möglichkeit gefunden, die Schaltfläche anzupassen. Sie können die Einstellung tintColorauf viewoder über einstellen appearanceWhenContainedIn, aber der Farbton verschwindet, sobald Sie ihn berühren. Immer noch auf der Suche nach Antworten.
Robert Chen
@AbdulMomen عبدالمؤمن Welche Fehlermeldung sehen Sie? Das Code-Snippet geht davon aus, dass FontAwesome bereits eingerichtet ist.
Robert Chen
1
@RobertChen, um das Problem zu lösen, setzen Sie einfach den Farbton nach: Können self.presentViewController(alertController, animated: true, completion: nil)wir die Schriftart der Schaltfläche "OK" ändern?
Hassan Taleb
4
Wird dies nicht als private API angesehen?
Jinghan Wang
13

Verwenden UIAppearanceProtokoll. Beispiel zum Festlegen einer Schriftart - Erstellen Sie eine Kategorie zum Erweitern 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

Und seine Verwendung:

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

Getestet und mit Stil gearbeitet UIAlertControllerStyleActionSheet, aber ich denke, es wird auch funktionieren UIAlertControllerStyleAlert.

PS Überprüfen Sie besser die Klassenverfügbarkeit anstelle der iOS-Version:

if ([UIAlertController class]) {
    // UIAlertController code (iOS 8)
} else {
    // UIAlertView code (pre iOS 8)
}
Ivan
quelle
Es funktioniert, aber auf diese Weise kann ich keine unterschiedliche Größe für Nachricht und Titel haben.
Libor Zapletal
Dies funktioniert, aber wenn auf eine Aktion geklickt wird, wird die Schriftgröße auf die ursprüngliche Größe zurückgesetzt. Passiert das für dich?
Larry
Ich habe das gleiche Problem @Larry und ich habe keinen Weg gefunden, damit umzugehen. Hast du?
Alasker
12

Verwenden UIAppearanceProtokoll. Machen Sie mehr Hacks mit appearanceFont, um die Schriftart für zu ändern UIAlertAction.

Erstellen Sie eine Kategorie für 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

Verwendung:

hinzufügen

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

in AppDelegate.m, um es für alle arbeiten UIAlertController.

user3480295
quelle
Der Titel in iOS 8.3 ist 13pt und fett, also habe ich die Bedingung inif (self.font.pointSize == 13 && isBold) {
Andrew Raphael
Sie haben erwähnt, dass Sie die Schriftart für ändern müssen UIAlertAction. Aber soweit ich das beurteilen kann, UIAlertActionwird kein a verwendet UILabel. Es verwendet eine NSString. github.com/nst/iOS-Runtime-Headers/blob/… Ich weiß nicht, wie Sie die Schriftart für eine anpassen können NSString.
Friedenstyp
UIAlertAction ist überhaupt keine Ansichtsklasse. Es ist eine abstrakte Klasse, die die Aktion beschreibt. Die Ansicht selbst wird dann in UIAlertController generiert. Sie legen daher das in UIAlertController enthaltene Erscheinungsbild fest.
mangerlahn
12

Swift 5 und 5.1 . Erstellen Sie eine separate Datei und geben Sie dort den UIAlertController-Anpassungscode ein

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

Jetzt Bei jeder Aktion Alarm anzeigen

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

Ergebnis

Geben Sie hier die Bildbeschreibung ein

Gurjinder Singh
quelle
1
Greifen wir hier auf private APIs zu? Haben Sie eine App mit diesen vielen benutzerdefinierten Warnungseigenschaften veröffentlicht?
Yash Bedi
@YashBedi verwendet private APIs und Apple lehnt Ihre App möglicherweise für die Verwendung als "nicht öffentliche API" ab. Nein, ich habe keine App veröffentlicht.
Gurjinder Singh
Dies wird auf der Apple-Entwicklerseite erwähnt -> Wichtig Die UIAlertController-Klasse soll unverändert verwendet werden und unterstützt keine Unterklassen. Die Ansichtshierarchie für diese Klasse ist privat und darf nicht geändert werden.
Gurjinder Singh
Verstanden, Boss. Danke.
Yash Bedi
@ Darkglow Bitte erwähnen Sie den Fehler. Ich bin in der Lage, den gleichen Code mit Swift 5.1
Gurjinder Singh
10

Ich benutze es.

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

Fügen Sie eine Zeile hinzu (AppDelegate) und funktioniert für alle UIAlertController.

Lucas Torquato
quelle
3
Da dies jetzt veraltet ist, verwenden Sie [[UIView ErscheinungsbildWhenContainedInInstancesOfClasses: @ [[UIAlertController-Klasse]]] setTintColor: newColor]; stattdessen
Peter Johnson
8

Swift 4

Beispiel für eine benutzerdefinierte Schriftart auf dem Titel. Gleiches gilt für andere Komponenten wie Nachrichten oder Aktionen.

    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)
AnthonyR
quelle
5

Hier ist eine Erweiterung für Swift 4.1 und 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")

}}
Vassilis A. Alexiou
quelle
4

Ich habe gerade einen Ersatz für abgeschlossen UIAlertController. Dies ist der einzig vernünftige Weg, denke ich:


Alt

Hier ist meine Methode in Swift, die viele Informationen aus den Antworten hier zusammenfasst

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

Dies funktioniert in einigen Situationen perfekt und in anderen ist es ein Totalausfall (die Farbtöne werden nicht wie erwartet angezeigt).

Dan Rosenstark
quelle
4

Sie können eine externe Bibliothek wie PMAlertController verwenden ohne verwenden, wobei Sie den nicht anpassbaren UIAlertController von Apple durch eine super anpassbare Warnung ersetzen können.

Kompatibel mit Xcode 8, Swift 3 und Objective-C

PMAlertController-Beispiel


Eigenschaften:

  • [x] Kopfzeilenansicht
  • [x] Header-Bild (optional)
  • [x] Titel
  • [x] Beschreibungsnachricht
  • [x] Anpassungen: Schriftarten, Farben, Abmessungen und mehr
  • [x] 1, 2 Tasten (horizontal) oder 3+ Tasten (vertikal)
  • [x] Schließen, wenn eine Taste gedrückt wird
  • [x] Unterstützung für Textfelder
  • [x] Ähnliche Implementierung wie UIAlertController
  • [x] Cocoapods
  • [x] Karthago
  • [x] Animation mit UIKit Dynamics
  • [x] Objective-C-Kompatibilität
  • [x] Swift 2.3 & Swift 3 Unterstützung
Paolo Musolino
quelle
Ermöglicht PMAlertController den Zeilenumbruch, wenn der Text in den Aktionsschaltflächen lang ist?
Zeeple
@zeeple Beachten Sie, dass die Aktionsschaltfläche eine Unterklasse von UIButton ist. So etwas actionButton.titleLabel.lineBreakMode = NSLineBreakByWordWrappingfunktioniert gut.
Paolo Musolino
3

Es gibt ein Problem beim Festlegen der Farbtonfarbe in der Ansicht nach der Präsentation. Selbst wenn Sie dies im Vervollständigungsblock von presentViewController tun: animiert: Vervollständigung:, verursacht dies einen Flackereffekt auf die Farbe der Schaltflächentitel. Das ist schlampig, unprofessionell und völlig inakzeptabel.

Andere vorgestellte Lösungen hängen davon ab, dass die Ansichtshierarchie statisch bleibt, was Apple nicht gerne tut. Erwarten Sie, dass diese Lösungen in zukünftigen Versionen von iOS fehlschlagen.

Der einzige sichere Weg, um dieses Problem zu lösen und es überall zu tun, besteht darin, UIAlertController eine Kategorie hinzuzufügen und viewWillAppear zu wechseln.

Der Header:

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

Die Umsetzung:

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

Fügen Sie Ihrem Projekt eine .pch (vorkompilierte Kopfzeile) hinzu und fügen Sie die Kategorie hinzu:

#import "UIAlertController+iOS9TintFix.h"

Stellen Sie sicher, dass Sie Ihre pch ordnungsgemäß im Projekt registrieren. Sie enthält die Kategoriemethoden in jeder Klasse, die den UIAlertController verwendet.

Importieren Sie dann in der didFinishLaunchingWithOptions-Methode Ihrer App-Delegierten Ihre Kategorie und rufen Sie sie auf

[UIAlertController tintFix];

und es wird automatisch an jede einzelne Instanz von UIAlertController in Ihrer App weitergegeben, unabhängig davon, ob sie von Ihrem Code oder von anderen gestartet wird.

Diese Lösung funktioniert sowohl für iOS 8.X als auch für iOS 9.X und es fehlt das Flimmern des Ansatzes zur Änderung des Farbtons nach der Präsentation. Es ist auch in Bezug auf die Ansichtshierarchie der Unteransichten des UIAlertControllers völlig agnostisch.

Viel Spaß beim Hacken!

ObiDan
quelle
Diese Lösung funktioniert meistens. Beim Drehen des Geräts kehren die Farbtöne jedoch wieder zu dem Zustand zurück, in dem sie sich vor dem Rauschen befanden.
Dhiraj Gupta
Dhiraj, ich habe dies gerade in einem Projekt-Setup explizit erneut getestet, um Ihre Ergebnisse zu untersuchen, und ich stimme dem nicht zu. Der Farbton kehrt nicht zu dem Zustand zurück, in dem er gedreht wurde.
ObiDan
Verifizierte Funktion unter xcode 6.4 und xcode 7.0. Ausführen von Simulatoren aller Variationen von 8.X und 9.0. Auf Wunsch werde ich das Projekt auf Github veröffentlichen.
ObiDan
Nun, Sie könnten weitermachen und ein Projekt aufstellen, aber genau das habe ich gesehen. Es funktionierte auch nicht auf dem iPad. Basierend auf Ihrer Methode Swizzling Idee, aber ich war der Lage, durch Umstellen viewDidLayoutSubviews funktioniert, though.
Dhiraj Gupta
Wenn Sie ein Projekt erstellen, kann ich eine Pull-Anfrage mit dem Swizzle viewDidLayoutSubviews senden. Diese habe ich gerade verwendet und in der neuesten Version meiner App an den App Store gesendet. Vielleicht können Sie einen Blick darauf werfen.
Dhiraj Gupta
3

Bitte finden Sie diese Kategorie. Ich kann FONT und Color von UIAlertAction und UIAlertController ändern.

Verwenden:

UILabel * appearanceLabel = [UILabel appearanceWhenContainedIn:UIAlertController.class, nil];
[appearanceLabel setAppearanceFont:yourDesireFont]];  
Arpan Dixit
quelle
5
Bitte fügen Sie den Code hier ein oder verwenden Sie einen Dienst, bei dem sich keine Personen anmelden müssen.
Sulthan
3

In Swift 4.1 und 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)
})
iOS
quelle
Ihre Antwort muss aktualisiert werden, self.present(alertController, animated: true)oder self.present(alert, animated: true).
Yash Bedi
@ Yash Bedi, danke, ich habe meine Antwort aktualisiert. Bitte überprüfe sie einmal.
iOS
2

Lösung / Hack für 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");
    }];
Akhilesh Sharma
quelle
Ich habe es versucht. Beachten Sie, dass Sie die Einstellung für die Fenstertönung zurücksetzen, sobald der Alarmcontroller angezeigt wird. Ich sehe die Farbe direkt auf dem Alarm-Controller zurückschalten. Ich glaube, die Umkehrung muss erfolgen, sobald eine Aktion getippt wird.
Germán
Vielen Dank an @ Germán für den Hinweis. Die Änderungen am Code wurden vorgenommen. Ich kümmere mich ab sofort um das Zurücksetzen in der AlertAction. Aber ja, ich stimme zu, dass dies auch im Dimiss-Handler behandelt werden kann
Akhilesh Sharma
1

Ich arbeite für Urban Outfitters. Wir haben einen Open Source Pod, den URBNAlertwir in all unseren Apps verwendet haben. Es basiert auf UIAlertController, ist aber hochgradig anpassbar.

Quelle ist hier: https://github.com/urbn/URBNAlert

Oder installieren Sie einfach durch den Pod, indem Sie ihn URBNAlertin Ihre Pod-Datei einfügen

Hier ist ein Beispielcode:

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];
RyanG
quelle
Unterstützt dies den ActionSheet-Stil?
Danpe
@ Danpe tut es nicht, es ist nur für Alerts .. Davon abgesehen .. wenn es etwas ist, das Sie wünschen, erstellen Sie ein Problem auf dem Repo. Das ist etwas, worüber wir bereits gesprochen haben
RyanG
1

Um die Farbe einer Schaltfläche wie CANCEL in die rote Farbe zu ändern, können Sie diese Stileigenschaft mit dem Namen UIAlertActionStyle.destructive verwenden:

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);
Kazim Ahmad
quelle
1

Verwenden Sie diesen Code für iOS 9.0 und höher in App Delegate

[[UIView appearanceWhenContainedInInstancesOfClasses:@[[UIAlertController class]]] setTintColor:[UIColor redColor]];
iOS
quelle
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")
Hiren Panchal
quelle
0

Ein bisschen klobig, aber das funktioniert gerade für mich, um Hintergrund- und Textfarben festzulegen. Ich habe es hier gefunden .

UIView * firstView = alertController.view.subviews.firstObject;
    UIView * nextView = firstView.subviews.firstObject;
    nextView.backgroundColor = [UIColor blackColor];
TheGeezer
quelle
Es funktioniert für die Hintergrundfarbe, aber es ändert nie die Farbtonfarbe, das ist, worüber ich ein bisschen verwirrt bin
Akhilesh Sharma
0

Ich habe eine Methode Ziel-C erstellt

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

Code wokring perfekt auf Xcode 8.3.1. Sie können nach Bedarf anpassen.

Alok
quelle
0

Ich benutze nur diese Art von Nachfrage, scheinbar und systematisch, Details sind etwas anders, also sind wir ... OC hat die Kapselung von Warn- und Blatt-Popup-Fenstern erkannt.

In der täglichen Entwicklung häufig anzutreffen ist es, eine Zahl zu Alert hinzuzufügen oder eine Schaltflächenfarbe zu ändern, wie z. B. "einfache" Anforderungen. Heutzutage sind Systemkomponenten sehr ähnlich und können die Anforderungen an kundenspezifische Verpackungskomponenten vollständig erfüllen.

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

Tim
quelle