Phông chữ, kích thước, màu sắc tùy chỉnh UIAlertController


118

Tôi đang sử dụng UIAlertController mới để hiển thị cảnh báo. Tôi có mã này:

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

Bây giờ tôi muốn thay đổi tiêu đề và phông chữ tin nhắn, màu sắc, kích thước, v.v. Cách tốt nhất để làm điều này là gì?

Chỉnh sửa: Tôi nên chèn toàn bộ mã. Tôi đã tạo danh mục cho UIView mà tôi có thể hiển thị cảnh báo phù hợp cho phiên bản 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:Cho bất kỳ ai đang đọc câu trả lời dưới đây. Apple sẽ từ chối (các) ứng dụng của bạn. Nếu bạn có xu hướng sử dụng bất kỳ (các) Api riêng tư nào. Và trong các câu trả lời bên dưới ĐÓ LÀ ĐIỀU GÌ XẢY RA ..
Yash Bedi

Câu trả lời:


98

Không chắc liệu điều này có chống lại các API / thuộc tính riêng tư hay không nhưng việc sử dụng KVC phù hợp với tôi trên 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"];

Đối với bản ghi, bạn cũng có thể thay đổi phông chữ của hành động cảnh báo bằng cách sử dụng các API riêng tư đó. Một lần nữa, nó có thể khiến ứng dụng của bạn bị từ chối, tôi vẫn chưa thử gửi mã như vậy.

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

Đối với Swift 4.2 trong XCode 10 trở lên, 2 dòng cuối cùng bây giờ là:

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

6
Nó đang hoạt động. attributedTitlecho tiêu đề và attributedMessagecho tin nhắn. Không chắc đó có phải là giải pháp tốt nhất hay không nhưng hiện tại nó đủ tốt cho tôi.
Libor Zapletal

2
tất cả những gì chúng ta có thể tùy chỉnh trên các nút UIAlertController ??
Aanchal Chaurasia

1
Cảm ơn! Tôi có một câu hỏi nhỏ - người ta có thể sử dụng phông chữ và màu sắc tùy chỉnh với ô thuộc tính và thông báo trong UIAlertController. Làm thế nào một người có thể làm điều tương tự với UIAlertAction?
p0lAris

72
Tôi hy vọng không ai trong số các bạn có kế hoạch phát hành ứng dụng này lên cửa hàng ứng dụng vì nó sử dụng các API riêng tư. Nghiêm túc mà nói, tôi không biết tại sao những câu trả lời này lại được chấp nhận trên Stackoverflow khi chúng không thực sự là 'câu trả lời'. Đây là những bản hack mà bạn có thể nhận được hoặc không thể tránh được khi xuất bản trong cửa hàng ứng dụng.
TheCodingArt

3
Đối với trường hợp phát hành ứng dụng trên cửa hàng ứng dụng, Apple cho phép một số việc sử dụng api riêng tư, nhưng không nên sử dụng api có thể gây hại hoặc ảnh hưởng đến hệ thống / quyền riêng tư của người dùng. Vì vậy, có lẽ câu trả lời này có thể được nhiều người chấp nhận chỉ vì điều này. Và có lẽ nó có thể không ảnh hưởng đến cửa hàng ứng dụng. Ai đó đã sử dụng cái này, có thể xác nhận rằng ứng dụng của họ không bị từ chối không?
Mehul Thakkar

66

Bạn có thể thay đổi màu của nút bằng cách áp dụng màu sắc cho UIAlertController.

Trên iOS 9, nếu màu cửa sổ được đặt thành màu tùy chỉnh, bạn phải áp dụng màu sắc ngay sau khi hiển thị cảnh báo. Nếu không, màu sắc sẽ được đặt lại thành màu cửa sổ tùy chỉnh của bạn.

// 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
Để làm rõ, thiết lập tintColor sau khi trình bày bộ điều khiển hoạt động trên cả iOS 8 và 9, vì vậy không cần thiết phải đặt nó hai lần.
arlomedia

Cảm ơn cho thêm một câu trả lời Swift và một cách giải quyết cho vấn đề này trong iOS 9.
peacetype

3
Khi tôi chạm và kéo ngón tay xuống, nó sẽ lại chuyển sang màu mặc định. Bất kỳ ý tưởng?
msmq

Đây thực sự là câu trả lời đàng hoàng duy nhất ở đây.
TheCodingArt

47

Bạn có thể thay đổi màu của văn bản nút bằng mã này:

alertC.view.tintColor = your color;

Có lẽ điều này sẽ giúp bạn.


@esilver bạn đã quản lý để tìm giải pháp hoạt động với iOS9 chưa?
Ash

1
Tôi không. Tôi đã tạo một báo cáo lỗi với Apple, # 22391695.
esilver

1
Thông tin thêm về điều này. Dường như khi bạn di chuyển trong một mục danh sách dài, là bạn chạm vào cuộn trở nên xanh ...
Bejil

3
Không có tính năng nào trong số này hoạt động trên UIAlertController trong iOS9 và 9.1 .. Không biết các nhà Apple đang làm gì ... Cần phải thay đổi màu cửa sổ theo cách thủ công mỗi khi bộ điều khiển cảnh báo được gọi và thay đổi lại trong trình xử lý.
Akhilesh Sharma

Nó hoạt động với iOS 9.3, trừ khi bạn chạm lên outiside: trở lại với màu xanh hệ thống
Rémi Belzanti

35

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

}

Đầu ra

Phông chữ, kích thước và màu sắc tùy chỉnh của UIAlertController


Xin lỗi người anh em, đây là khởi động. Nếu được yêu cầu trong tính năng, tôi sẽ thông báo cho bạn ...
iOS

24

Bản dịch nhanh của câu trả lời @ Dupuis2387. Tìm ra cú pháp để đặt UIAlertControllermàu sắc và phông chữ của tiêu đề thông qua KVC bằng cách sử dụng attributedTitlephím.

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)

nhập mô tả hình ảnh ở đây


3
Còn về nút "OK"? Chúng tôi có thể tùy chỉnh nó?
Hassan Taleb

@HassanTaleb Tôi chưa tìm ra cách hay để tùy chỉnh nút. Bạn có thể tintColorbật viewhoặc qua appearanceWhenContainedIn, nhưng sắc thái sẽ biến mất ngay khi bạn chạm vào. Vẫn đang tìm kiếm câu trả lời.
Robert Chen

@AbdulMomen عبدالمؤمن Bạn đang thấy thông báo lỗi nào? Đoạn mã giả định FontAwesome đã được thiết lập.
Robert Chen

1
@RobertChen để giải quyết vấn đề chỉ cần đặt màu sau : self.presentViewController(alertController, animated: true, completion: nil), chúng ta có thể thay đổi phông chữ của nút "OK" không?
Hassan Taleb

4
Đây không được coi là một api riêng?
Jinghan Wang

13

Sử dụng UIAppearancegiao thức. Ví dụ để đặt phông chữ - tạo một danh mục để mở rộng 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

Và cách sử dụng của nó:

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

Đã thử nghiệm và làm việc với phong cách UIAlertControllerStyleActionSheet, nhưng tôi đoán nó cũng sẽ hoạt động với UIAlertControllerStyleAlert.

PS Kiểm tra tốt hơn tính khả dụng của lớp học thay vì phiên bản iOS:

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

Nó hoạt động nhưng theo cách này, tôi không thể có kích thước khác nhau cho tin nhắn và cho tiêu đề.
Libor Zapletal

Điều này hoạt động nhưng khi một hành động được nhấp vào, phông chữ sẽ trở lại kích thước ban đầu? Điều này có xảy ra với bạn không?
Larry

Tôi cũng gặp phải vấn đề tương tự @Larry và tôi chưa tìm ra cách giải quyết .. bạn nhỉ?
alasker

12

Sử dụng UIAppearancegiao thức. Thực hiện nhiều cách hack hơn với appearanceFontđể thay đổi phông chữ cho UIAlertAction.

Tạo một danh mục cho 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

Sử dụng:

thêm vào

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

trong AppDelegate.mđể làm cho nó làm việc cho tất cả UIAlertController.


Tiêu đề của iOS 8.3 là 13pt và đậm vì vậy tôi đã thay đổi điều kiện đểif (self.font.pointSize == 13 && isBold) {
Andrew Raphael

Bạn đã đề cập đến việc thay đổi phông chữ cho UIAlertAction. Nhưng theo như tôi có thể nói, UIAlertActionkhông sử dụng a UILabel. Nó sử dụng một NSString. github.com/nst/iOS-Runtime-Headers/blob/… Tôi không biết làm cách nào bạn có thể tùy chỉnh phông chữ cho an NSString.
Peacetype

UIAlertAction hoàn toàn không phải là một lớp xem. Nó là một lớp trừu tượng mô tả hành động. Sau đó, bản thân khung nhìn được tạo bên trong UIAlertController. Do đó, bạn đặt giao diện có trong UIAlertController.
mangerlahn

12

Swift 5 và 5.1 . Tạo một tệp riêng biệt và đặt mã Tùy chỉnh 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
  }
}

Hiện hành động Hiển thị cảnh báo

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

Kết quả

nhập mô tả hình ảnh ở đây


1
chúng tôi đang truy cập bất kỳ Api riêng tư nào ở đây.? bạn đã phát hành ứng dụng nào có nhiều thuộc tính cảnh báo tùy chỉnh này chưa?
Yash Bedi

@YashBedi nó đang sử dụng các API riêng tư và Apple có thể từ chối ứng dụng của bạn để sử dụng "API không công khai". Không, tôi chưa phát hành bất kỳ ứng dụng nào.
Gurjinder Singh

Điều này được đề cập trên trang web dành cho nhà phát triển của Apple -> Quan trọng Lớp UIAlertController được thiết kế để sử dụng nguyên trạng và không hỗ trợ phân lớp. Hệ thống phân cấp dạng xem cho lớp này là riêng tư và không được sửa đổi.
Gurjinder Singh

Đã hiểu rồi Ông chủ Cảm ơn bạn.
Yash Bedi

@Darkglow Vui lòng đề cập đến lỗi. Tôi có thể tạo thành công cùng một mã với nhanh chóng 5.1
Gurjinder Singh

10

Tôi đang sử dụng nó.

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

Thêm một dòng (AppDelegate) và hoạt động cho tất cả UIAlertController.


3
Vì tính năng này hiện không được dùng nữa, hãy sử dụng [[UIView ngoại hìnhWhenContainedInInstancesOfClasses: @ [[[lớp UIAlertController]]] setTintColor: newColor]; thay vào đó
Peter Johnson

8

Swift 4

Ví dụ về phông chữ tùy chỉnh trên tiêu đề. Những thứ tương tự cho các thành phần khác như tin nhắn hoặc hành động.

    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

Đây là phần mở rộng cho Swift 4.1 và 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

Tôi vừa hoàn thành thay thế cho UIAlertController. Đây là cách hợp lý duy nhất để đi, tôi nghĩ:


Đây là phương pháp của tôi trong Swift, cung cấp nhiều thông tin từ các câu trả lời ở đây

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

Điều này hoạt động hoàn hảo trong một số trường hợp, và trong một số trường hợp khác, nó hoàn toàn không thành công (màu sắc không hiển thị như mong đợi).


4

Bạn có thể sử dụng thư viện bên ngoài như PMAlertController mà không cần sử dụng giải pháp thay thế, nơi bạn có thể thay thế UIAlertController không thể tùy chỉnh của Apple bằng một cảnh báo siêu tùy chỉnh.

Tương thích với Xcode 8, Swift 3 và Objective-C

Ví dụ về PMAlertController


Đặc trưng:

  • [x] Chế độ xem Tiêu đề
  • [x] Hình ảnh tiêu đề (Tùy chọn)
  • [x] Tiêu đề
  • [x] Thông báo mô tả
  • [x] Tùy chỉnh: phông chữ, màu sắc, kích thước và hơn thế nữa
  • [x] 1, 2 nút (theo chiều ngang) hoặc 3+ nút (theo chiều dọc)
  • [x] Đóng khi một nút được nhấn
  • [x] Hỗ trợ Trường Văn bản
  • [x] Triển khai tương tự với UIAlertController
  • [x] Cocoapods
  • [x] Carthage
  • [x] Hoạt ảnh với UIKit Dynamics
  • [x] Khả năng tương thích Objective-C
  • [x] Hỗ trợ Swift 2.3 & Swift 3

PMAlertController có cho phép gói từ khi văn bản dài trong các nút hành động không?
zeeple

@zeeple coi rằng nút hành động là một lớp con của UIButton. Một cái gì đó như vậy actionButton.titleLabel.lineBreakMode = NSLineBreakByWordWrappinghoạt động tốt.
Paolo Musolino

3

Có vấn đề với việc đặt màu sắc trên chế độ xem sau khi trình bày; ngay cả khi bạn làm điều đó trong khối hoàn thành của presentViewController: animation: complete :, nó gây ra hiệu ứng nhấp nháy trên màu sắc của tiêu đề nút. Điều này là cẩu thả, thiếu chuyên nghiệp và hoàn toàn không thể chấp nhận được.

Các giải pháp khác được trình bày phụ thuộc vào hệ thống phân cấp chế độ xem vẫn ở trạng thái tĩnh, điều mà Apple không thích làm. Hy vọng những giải pháp đó sẽ không thành công trong các bản phát hành iOS trong tương lai.

Một cách chắc chắn để giải quyết vấn đề này và thực hiện nó ở mọi nơi, là thêm một danh mục vào UIAlertController và thay đổi viewWillAppear.

Tiêu đề:

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

Việc thực hiện:

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

Thêm .pch (tiêu đề được biên dịch trước) vào dự án của bạn và bao gồm danh mục:

#import "UIAlertController+iOS9TintFix.h"

Đảm bảo rằng bạn đăng ký pch của mình trong dự án đúng cách và nó sẽ bao gồm các phương thức danh mục trong mọi lớp sử dụng UIAlertController.

Sau đó, trong phương thức đại biểu ứng dụng didFinishLaunchingWithOptions của bạn, hãy nhập danh mục của bạn và gọi

[UIAlertController tintFix];

và nó sẽ tự động phổ biến đến mọi phiên bản UIAlertController trong ứng dụng của bạn, cho dù được khởi chạy bởi mã của bạn hay của bất kỳ ai khác.

Giải pháp này hoạt động cho cả iOS 8.X và iOS 9.X và không có sự nhấp nháy của phương pháp thay đổi sắc thái sau khi trình bày. Nó cũng hoàn toàn bất khả tri đối với phân cấp chế độ xem của các chế độ xem phụ của UIAlertController.

Chúc bạn hack vui vẻ!


Giải pháp này hầu hết đều hoạt động. Tuy nhiên, khi xoay thiết bị, các sắc thái sẽ trở lại như cũ, trước khi thay đổi.
Dhiraj Gupta

Dhiraj, tôi vừa thử nghiệm điều này một lần nữa trong thiết lập dự án một cách rõ ràng để khám phá những phát hiện của bạn, và tôi không đồng ý. Màu sắc không trở lại như cách nó đã được xoay.
ObiDan

Đã xác minh chức năng trên xcode 6.4 và xcode 7.0. Chạy trình mô phỏng của tất cả các biến thể của 8.X và 9.0. Nếu được yêu cầu, tôi sẽ đưa dự án lên github.
ObiDan

Bạn có thể tiếp tục và lập một dự án, nhưng đây là những gì tôi đang thấy đang xảy ra với mình. Nó cũng không hoạt động trên iPad. Dựa trên ý tưởng phương pháp swizzling của bạn, tuy nhiên, tôi đã có thể để làm cho nó hoạt động bằng cách viewDidLayoutSubviews swizzling, mặc dù.
Dhiraj Gupta

Nếu bạn đưa ra một dự án, thì tôi có thể gửi một yêu cầu kéo bằng cách sử dụng viewDidLayoutSubviews, đây là thứ mà tôi vừa sử dụng và gửi trong bản dựng ứng dụng mới nhất của mình lên App Store và bạn có thể xem, có thể chứ?
Dhiraj Gupta

3

Vui lòng tìm danh mục này . Tôi có thể thay đổi FONT và Màu của UIAlertAction và UIAlertController.

Sử dụng:

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

5
Vui lòng dán mã vào đây hoặc sử dụng dịch vụ không yêu cầu mọi người đăng nhập.
Sulthan

3

Trong Swift 4.1 và 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)
})

câu trả lời của bạn cần được cập nhật, self.present(alertController, animated: true)hoặc self.present(alert, animated: true).
Yash Bedi

@Yash Bedi, cảm ơn bạn, tôi đã cập nhật câu trả lời của mình, vui lòng kiểm tra nó một lần.
iOS

2

Giải pháp / Hack cho 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");
    }];

Tôi đã thử cái này. Lưu ý rằng bạn đang hoàn nguyên cài đặt màu cửa sổ sau khi bộ điều khiển cảnh báo được hiển thị. Tôi thấy màu chuyển trở lại ngay trên bộ điều khiển cảnh báo. Tôi tin rằng việc hoàn nguyên phải được thực hiện khi bất kỳ hành động nào được nhấn.
Germán

Cảm ơn @ Germán đã chỉ ra điều đó .. Đã thực hiện các thay đổi đối với mã. Tôi đang xử lý hoàn nguyên trong AlertAction như của bây giờ .. Nhưng có, tôi đồng ý rằng có thể được xử lý trong xử lý dimiss quá
Akhilesh Sharma

1

Tôi làm việc cho Urban Outfitters. Chúng tôi có một nhóm mã nguồn mở URBNAlertmà chúng tôi đã sử dụng trong tất cả các ứng dụng của mình. Nó dựa trên UIAlertController, nhưng có khả năng tùy biến cao.

Nguồn ở đây: https://github.com/urbn/URBNAlert

Hoặc chỉ cần cài đặt theo pod bằng cách đặt URBNAlertvào Podfile của bạn

Đây là một số mã mẫu:

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

Điều này có hỗ trợ kiểu ActionSheet không?
Danpe

@Danpe thì không, nó hoàn toàn chỉ dành cho Cảnh báo .. Điều đó đang được nói .. nếu điều gì đó bạn mong muốn tạo ra vấn đề trên repo. Đó là điều mà chúng tôi đã thảo luận về việc thêm hỗ trợ trước đó
RyanG

1

Để thay đổi màu của một nút như CANCEL thành màu đỏ, bạn có thể sử dụng thuộc tính kiểu này có tên là 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

Đối với iOS 9.0 trở lên, hãy sử dụng mã này trong ứng dụng ủy quyền

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

1

Swift 5.0

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

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

0

Hơi rắc rối, nhưng điều này phù hợp với tôi ngay bây giờ để thiết lập màu nền và văn bản. Tôi đã tìm thấy nó ở đây .

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

Nó không làm việc cho màu nền nhưng nó không bao giờ thay đổi màu sắc màu này là những gì Tôi là một chút nhầm lẫn về
Akhilesh Sharma

0

Tôi đã tạo một mục tiêu phương pháp-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];
}

Mã chạy hoàn hảo trên Xcode 8.3.1. Bạn có thể tùy chỉnh theo yêu cầu.


0

Tôi chỉ sử dụng loại nhu cầu này, dường như và hệ thống, các chi tiết hơi khác nhau, vì vậy chúng tôi ... OC nhận ra Alert và Sheet popup window đóng gói.

Thường gặp trong quá trình phát triển hàng ngày cần thêm một con số vào Cảnh báo hoặc thay đổi màu nút, chẳng hạn như nhu cầu "đơn giản", ngày nay mang đến một và các thành phần hệ thống có độ tương đồng cao và có thể đáp ứng đầy đủ nhu cầu của các thành phần đóng gói tùy chỉnh.

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.