UIAlertController користувальницький шрифт, розмір, колір


118

Я використовую новий UIAlertController для показу сповіщень. У мене є цей код:

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

Тепер я хочу змінити шрифт заголовка та повідомлення, колір, розмір тощо. Який найкращий спосіб зробити це?

Редагувати: я повинен вставити цілий код. Я створив категорію для UIView, що можу показувати правильне сповіщення для версії 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:Кожен, хто читає наведені нижче відповіді. Apple відхилить ваші програми. Якщо ви схильні використовувати будь-які приватні Api (и). А в нижченаведеній відповіді
Yash Bedi

Відповіді:


98

Не впевнений, чи це проти приватних API / властивостей, але використання KVC працює для мене на 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"];

Для запису можна також змінити шрифт дії попередження, використовуючи ці приватні API. Знову ж, можливо, ваш додаток буде відхилено, я ще не намагався надіслати такий код.

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

Для Swift 4.2 в XCode 10 і вище останні два рядки тепер:

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

6
Це працює. attributedTitleдля заголовка та attributedMessageдля повідомлення. Не впевнений, чи найкраще це рішення, але наразі це досить добре для мене.
Libor Zapletal

2
які всі налаштування ми можемо додати на кнопки UIAlertController ??
Aanchal Chaurasia

1
Дякую! У мене є невелике запитання - можна використовувати спеціальні шрифти та кольори з плиткою атрибутів та повідомленням у UIAlertController. Як можна зробити те саме UIAlertAction?
p0lAris

72
Сподіваюся, ніхто з вас не планує випускати це в магазин додатків, оскільки він використовує приватні API. Якщо серйозно, я не маю поняття, чому ці відповіді колись приймаються в Stackoverflow, коли вони насправді не "відповіді". Це хаки, від яких ви можете або не уникнете публікації в магазині додатків.
TheCodingArt

3
У випадку випуску програми в магазині додатків Apple дозволено деякі приватні використання програм, але він не повинен використовувати apis, який може завдати шкоди або вплинути на систему / конфіденційність користувача. Тож, ймовірно, ця відповідь може бути сприйнята багатьма людьми лише завдяки цьому. І, можливо, це не вплине на магазин додатків. Чи може хтось, хто цим скористався, може підтвердити, що їх додаток не відхилено?
Мехул Таккар

66

Ви можете змінити колір кнопки, застосувавши колір відтінку до UIAlertController.

У iOS 9, якщо колір відтінку вікна було встановлено у власному кольорі, вам слід застосувати колір відтінку відразу після подання попередження. Інакше колір відтінку буде скинутий на ваш власний колір відтінку вікна.

// 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
Для уточнення, встановлення tintColor після подання контролера працює як на iOS 8, так і на 9, тому його не потрібно встановлювати двічі.
arlomedia

Дякуємо, що додали відповідь Swift та
вирішили

3
Коли я натискаю і перетягую палець вниз, він знову перейде до кольору за замовчуванням. Будь-яка ідея?
msmq

Це справді єдина гідна відповідь.
TheCodingArt

47

Ви можете змінити колір тексту кнопки за допомогою цього коду:

alertC.view.tintColor = your color;

Можливо, це вам допоможе.


@esilver вам вдалося знайти рішення, яке працює з iOS9?
Еш

1
Я не. Я створив звіт про помилку з Apple, # 22391695.
esilver

1
Більше інформації про це. Здається, що коли ви прокручуєте елементи довгих списків, той, який ви торкаєтесь для прокрутки, стає блакитним ...
Bejil

3
Нічого з цього не працює на UIAlertController в iOS9 та 9.1. Не знаєте, на що хлопці Apple піднімаються ... Потрібно вручну змінювати відтінок вікна щоразу, коли викликається контролер сповіщення, і змінити його назад у обробнику.
Ахілеш Шарма

Він працює з iOS 9.3, якщо ви не торкаєтесь сторонніх сторін: повертається до системного синього кольору
Rémi Belzanti

35

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

}

Вихідні дані

UIAlertController нестандартний шрифт, розмір та колір


Вибачте, брате, це запуск. Якщо потрібно в функції, я повідомляю вам ...
iOS

24

Швидкий переклад відповіді @ dupuis2387 Опрацював синтаксис, щоб задати UIAlertControllerколір і шрифт заголовка через KVC за допомогою attributedTitleклавіші.

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)

введіть тут опис зображення


3
А як щодо кнопки "ОК"? Чи можемо ми це налаштувати?
Хасан Талеб

@HassanTaleb Я не знайшов чудового способу налаштувати кнопку. Ви можете встановити tintColorна viewабо через appearanceWhenContainedIn, але відтінок зникає, як тільки ви торкаєтесь його. Але все ще шукаю відповіді.
Роберт Чен

@AbdulMomen عبدالمؤمن Яке повідомлення про помилку ви бачите? Фрагмент коду передбачає, що FontAwesome вже налаштований.
Роберт Чен

1
@RobertChen для вирішення проблеми просто нанесіть відтінок після: чи self.presentViewController(alertController, animated: true, completion: nil)можемо ми змінити шрифт кнопки "ОК"?
Хасан Талеб

4
Це не вважається приватною api?
Jinghan Wang

13

Використовуйте UIAppearanceпротокол. Приклад встановлення шрифту - створіть категорію для розширення 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

І його використання:

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

Випробували та працювали зі стилем UIAlertControllerStyleActionSheet, але, мабуть, UIAlertControllerStyleAlertтеж буде працювати .

PS Краще перевірити наявність класу замість версії iOS:

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

Це працює, але таким чином я не можу мати різний розмір для повідомлення та для заголовка.
Libor Zapletal

Це працює, але при натисканні на дію шрифт повертається до початкового розміру? Це трапляється для вас?
Ларрі

У мене така ж проблема @Larry, і я не знайшов способу вирішити це.
тупик

12

Використовуйте UIAppearanceпротокол. Робіть більше злому, appearanceFontщоб змінити шрифт UIAlertAction.

Створіть категорію для 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

Використання:

додати

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

в , AppDelegate.mщоб змусити його працювати на всіх UIAlertController.


Заголовок в iOS 8.3 є 13-кратним і жирним, тому я змінив умову наif (self.font.pointSize == 13 && isBold) {
Ендрю Рафаель,

Ви згадали про зміну шрифту для UIAlertAction. Але наскільки я можу сказати, UIAlertActionне використовує а UILabel. Він використовує NSString. github.com/nst/iOS-Runtime-Headers/blob/… Я не знаю, як можна налаштувати шрифт для NSString.
миротип

UIAlertAction - це зовсім не клас перегляду. Це абстрактний клас, що описує дію. Сам вигляд потім генерується всередині UIAlertController. Тому ви встановлюєте зовнішній вигляд, що міститься в UIAlertController.
mangerlahn

12

Швидкі 5 та 5.1 . Створіть окремий файл і покладіть туди код налаштування 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
  }
}

Тепер про будь-яку дію Показати сповіщення

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

Результат

введіть тут опис зображення


1
ми звертаємось до будь-якого приватного Api тут. Ви випустили будь-яку програму з цими багатьма властивостями власного сповіщення?
Яш Беді

@YashBedi використовує приватні API та Apple може відхилити ваш додаток для використання "непублічного API". Ні, я не випустив жодної програми.
Gurjinder Singh

Про це йдеться на сайті розробника Apple -> Важливо Клас UIAlertController призначений для використання як є та не підтримує підкласифікацію. Ієрархія перегляду для цього класу є приватною і не повинна змінюватися.
Гурджиндер Сінгх

Зрозумів, бос, дякую.
Яш Беді

@Darkglow Будь ласка, згадайте про помилку. Я можу успішно створити той самий код із швидким 5.1
Gurjinder Singh

10

Я цим користуюся.

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

Додайте один рядок (AppDelegate) і працює для всіх UIAlertController.


3
Оскільки це тепер застаріло, використовуйте [[UIView lookWhenContainInInsancesOfClasses: @ [[клас UIAlertController]]] setTintColor: newColor]; натомість
Пітер Джонсон

8

Швидкий 4

Приклад спеціального шрифту на заголовку. Те саме, що стосується інших компонентів, таких як повідомлення або дії.

    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

Ось розширення для Swift 4.1 та 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

Я щойно завершив заміну на UIAlertController. Це єдиний розумний шлях, я думаю:


Старий

Ось мій метод у Swift, який накопичує багато інформації з відповідей тут

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

У деяких ситуаціях це ідеально, а в інших - тотальний збій (відтінки кольорів не показуються, як очікувалося).


4

Ви можете використовувати зовнішню бібліотеку, наприклад PMAlertController, не застосовуючи обхідних шляхів, де ви можете замінити непристосований UIAlertController від Apple надзвичайно настроюваним попередженням.

Сумісний з Xcode 8, Swift 3 та Objective-C

Приклад PMAlertController


Особливості:

  • [x] Перегляд заголовка
  • [x] Зображення заголовка (необов’язково)
  • [x] Назва
  • [x] Опис повідомлення
  • [x] Настроювання: шрифти, кольори, розміри та багато іншого
  • [x] 1, 2 кнопки (горизонтально) або 3+ кнопки (вертикально)
  • [x] Закриття при натисканні кнопки
  • [x] Підтримка текстових полів
  • [x] Аналогічна реалізація UIAlertController
  • [x] Какаоди
  • [x] Карфаген
  • [x] Анімація за допомогою UIKit Dynamics
  • [x] Сумісність Objective-C
  • [x] Підтримка Swift 2.3 та Swift 3

Чи дозволяє PMAlertController для обертання слів, коли текст довгий на кнопках дій?
zeeple

@zeeple вважають, що кнопка дії є підкласом UIButton. Щось подібне actionButton.titleLabel.lineBreakMode = NSLineBreakByWordWrappingпрацює добре.
Паоло Мусоліно

3

Виникає проблема із встановленням кольору відтінку на зображенні після подання; навіть якщо ви робите це в блоці завершення представленого ViewViewController: animed: завершення :, це викликає ефект мерехтіння на колір заголовків кнопок. Це неохайно, непрофесійно і зовсім неприпустимо.

Інші представлені рішення залежать від того, що статична ієрархія перегляду залишається статичною, що Apple ненавидить робити. Очікуйте, що ці рішення не зможуть у майбутніх випусках iOS.

Єдиний надійний спосіб вирішити цю проблему та зробити це скрізь - це додавання категорії до UIAlertController та шиблення видуWillAppear.

Заголовок:

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

Впровадження:

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

Додайте .pch (попередньо складений заголовок) до свого проекту та додайте категорію:

#import "UIAlertController+iOS9TintFix.h"

Переконайтесь, що ви зареєстрували свій pch у проекті належним чином, і він буде включати методи категорії у кожному класі, який використовує UIAlertController.

Потім у вашому додатку делеґенти didFinishLaunchingWithOptions методом імпортуйте свою категорію та зателефонуйте

[UIAlertController tintFix];

і він автоматично поширюватиметься на кожен окремий екземпляр UIAlertController у вашій програмі, незалежно від того, запущений вашим кодом або чиїсь інші.

Це рішення працює як для iOS 8.X, так і для iOS 9.X і не має мерехтіння підходу після презентації зміни відтінку. Він також є абсолютно агностичним щодо ієрархії подання підпогляду UIAlertController.

Щасливий злом!


Це рішення працює, здебільшого. Однак при обертанні пристрою відтінки повертаються такими, якими вони були, до шиплячих.
Dhiraj Gupta

Dhiraj, я просто перевірив це ще раз у програмі проекту, щоб явно вивчити ваші висновки, і я не згоден. Відтінок не повертається до того, як він був на повороті.
ObiDan

Перевірено функціоналом на xcode 6.4 та xcode 7.0. Запуск тренажерів усіх варіацій 8.X та 9.0. Якщо я вимагаю, я виставлю проект на github.
ObiDan

Добре, ви могли б продовжувати і ставити проект, але це те, що я бачив зі мною. Він також не працював на iPad. Однак, виходячи із вашої задумливої ​​ідеї методу, я все ж зміг змусити її працювати за допомогою шипучого viewDidLayoutSubviews.
Дхірадж Гупта

Якщо ви поставите проект, то я можу надіслати запит на тягу за допомогою свистка viewDidLayoutSubviews. Це те, що я тільки що використав і подав у останній збірці свого додатка в App Store, і ви можете подивитися?
Dhiraj Gupta

3

Будь ласка, знайдіть цю категорію. Я в змозі змінити FONT і Color UIAlertAction та UIAlertController.

Використання:

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

5
Будь ласка, вставте тут код або скористайтеся сервісом, який не вимагає входу людей.
Sultahan

3

У Swift 4.1 та 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)
})

Ваша відповідь потребує оновлення, self.present(alertController, animated: true)або self.present(alert, animated: true).
Яш Беді

@Yash Bedi, дякую, я оновив свою відповідь, будь ласка, перевірити її один раз.
iOS

2

Рішення / злом для 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");
    }];

Я спробував це. Зауважте, що ви скасовуєте налаштування відтінку вікна, коли представлений контролер попередження. Я бачу перемикання кольору прямо на контролері оповіщення. Я вважаю, що повернення повинно бути здійснено, коли будь-яка дія буде здійснена.
Герман

Дякую @ Germán за вказівку на це. Внесли зміни в код. Відтепер я обробляю ревертування в AlertAction .. Але так, я згоден, що це може бути вирішено і в обробці диміса
Ахілеш Шарма

1

Я працюю у Urban Outfitters. У нас є відкритий код джерела URBNAlert, який ми використовували у всіх наших додатках. Він заснований на UIAlertController, але налаштовується на високому рівні.

Джерело тут: https://github.com/urbn/URBNAlert

Або просто встановити стручок, помістивши URBNAlertу свій Podfile

Ось такий зразок коду:

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

Чи підтримує це стиль ActionSheet?
Данпе

@Danpe це не так, це суто для сповіщень .. Це, як говорять .. якщо його щось ви хочете створити проблему на репо. Це те, про що ми говорили, додаючи підтримку раніше
RyanG

1

Щоб змінити колір однієї кнопки на зразок CANCEL на червоний, ви можете скористатися цим стилем властивості під назвою 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

Для iOS 9.0 і вище використовуйте цей код у делеґаті програми

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

1

Швидкий 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

Трохи незграбний, але це працює для мене зараз, щоб встановити кольори фону та тексту. Я знайшов це тут .

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

Це працює для фонового кольору, але він ніколи не змінює колір відтінку. Це те, про що я трохи заплутався
Ахілеш Шарма

0

Я створив один метод-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];
}

Код ідеально працює на Xcode 8.3.1. Ви можете налаштувати відповідно до вимог.


0

Я просто використовую такий вид попиту, здавалося б, системний, деталі дещо відрізняються, тому ми ... OC зрозумів, інкапсуляція спливаючих вікон повідомлень та листів.

Часто зустрічаються у щоденній розробці потребують додати фігуру до сигналу або змінити колір кнопки, такий як "простий" попит, сьогодні приносить і системні компоненти дуже схожі і можуть повністю задовольнити попит на спеціальні компоненти упаковки.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.