Пользовательский шрифт UIAlertController, размер, цвет
Я использую новый 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];
теперь я хочу изменить заголовок и шрифт сообщения, цвет, размер и так далее. Как лучше всего это сделать?
Edit: Я должен вставить весь код. Я создал категорию для 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];
}
}
22 ответа:
Не уверен, что это против частных 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
вы можете изменить цвет кнопки, применив цвет оттенка к 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()
вы можете изменить цвет текста кнопки с помощью этого кода:
alertC.view.tintColor = your color;
может быть, это поможет вам.
В 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) }
выход
быстрый перевод ответа @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)
использовать
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
тоже.П. С. лучше проверить наличие билетов класс вместо версии iOS:
if ([UIAlertController class]) { // UIAlertController code (iOS 8) } else { // UIAlertView code (pre iOS 8) }
использовать
UIAppearance
протокол. Сделайте больше хаков сappearanceFont
чтобы изменить шрифт дляUIAlertAction
.создать Категорию для
UILabel
UILabel + FontAppearance.h
@interface UILabel (FontAppearance) @property (nonatomic, copy) UIFont * appearanceFont UI_APPEARANCE_SELECTOR; @end
UILabel + FontAppearance.м
@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
.
Я использую его.
[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor blueColor]];
добавить одну строку (AppDelegate) и работает для всех UIAlertController.
Swift 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)
существует проблема с установкой оттенка цвета на вид после представления; даже если вы делаете это в блоке завершения presentViewController:animated:completion:, это вызывает эффект мерцания на цвет заголовков кнопок. Это небрежно, непрофессионально и совершенно недопустимо.
другие представленные решения зависят от того, что иерархия представлений остается статичной, что Apple ненавидит делать. Ожидайте, что эти решения потерпят неудачу в будущих выпусках усвн.
один верный способ решить эту проблему и сделать это везде - это добавить категорию В UIAlertController и прокрутить viewWillAppear.
заголовок:
// // 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
добавить a .pch (precompiled header) к вашему проекту и включите категорию:
#import "UIAlertController+iOS9TintFix.h"
убедитесь, что вы правильно зарегистрировали свой pch в проекте, и он будет включать методы категории в каждом классе, который использует UIAlertController.
затем в вашем приложении делегаты didFinishLaunchingWithOptions метод, импортировать категорию и вызвать
[UIAlertController tintFix];
и он будет автоматически распространяться на каждый экземпляр UIAlertController в вашем приложении, независимо от того, запущен ли ваш код или чей-либо еще.
это решение работает как для iOS 8.X и iOS 9.X и не хватает мерцания оттенка изменить пост-презентационный подход. Он также полностью агностичен в отношении иерархии представления суб-вид на UIAlertController.
всего доброго!
Я только что закончил замену
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) } } }
это работает в некоторых ситуациях отлично, а в других это полный провал (оттенок цвета не показывают, как ожидалось).
решение/хак для 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"); }];
вы можете использовать внешнюю библиотеку, как PMAlertController без использования обходного пути, где вы можете заменить uncustomizable UIAlertController от Apple с супер настраиваемым предупреждением.
совместимость с Xcode 8, Swift 3 и Objective-C
характеристики:
- [x] вид заголовка
- [x] изображение заголовка (необязательно)
- [x] Название
- [x] описание сообщения
- [x] настройки: шрифты, цвета, размеры и многое другое
- [x] 1, 2 кнопки (по горизонтали) или 3 + кнопки (по вертикали)
- [x] закрытие при нажатии кнопки
- [x] поддержка текстовых полей
- [x] аналогичная реализация UIAlertController
- [x] Cocoapods
- [x] Карфаген
- [x] анимация с динамикой UIKit
- [x] Цель-с совместимости
- [x] Swift 2.3 & Swift 3 поддержка
Я работаю на Urban Outfitters. У нас есть стручок с открытым исходным кодом,
URBNAlert
, который мы использовали во всех наших приложений. Он основан наUIAlertController
, но настраиваемый.источник здесь:https://github.com/urbn/URBNAlert
или просто установите стручком путем устанавливать
URBNAlert
в свой файл контейнеравот пример кода:
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];
пожалуйста, найдите этой. Я могу изменить шрифт и цвет UIAlertAction и UIAlertController.
использование:
UILabel * appearanceLabel = [UILabel appearanceWhenContainedIn:UIAlertController.class, nil]; [appearanceLabel setAppearanceFont:yourDesireFont]];
вот расширение для 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") }}
немного неуклюжим, но это работает для меня прямо сейчас, чтобы установить цвет фона и текста. Я нашел его здесь.
UIView * firstView = alertController.view.subviews.firstObject; UIView * nextView = firstView.subviews.firstObject; nextView.backgroundColor = [UIColor blackColor];
чтобы изменить цвет одной кнопки, например отмена, на красный цвет, вы можете использовать это свойство стиля под названием UIAlertActionStyle.разрушительный :
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);
Я создал один метод 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]; }
код wokring отлично на Xcode 8.3.1. Вы можете настроить в соответствии с требованиями.
Я просто использую такой спрос, казалось бы, и система, детали немного отличаются, так что мы ... Ок понял, оповещения и лист заключения всплывающем окне.
часто встречаемая в ежедневной потребности развития добавить диаграмму для того чтобы предупредить или изменить цвет кнопки, как "простое" требование, сегодня приносит А и компоненты системы сильно подобного и может полно соотвествовать подгонянный упаковывать комплектующие.
для iOS 9.0 и выше используйте этот код в приложение делегат
[[UIView appearanceWhenContainedInInstancesOfClasses:@[[UIAlertController class]]] setTintColor:[UIColor redColor]];
в Swift 4.1 и Xcode 9.4.1
//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(alertController, animated: true) })