4

I would like to know if there's a way to show HTML in the message of a UIAlertController.

Android has a way to do it, but I cannot find a way to do the same on iOS. I'm using Swift 3 right now.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • 2
    Possible duplicate of [Html file inside an AlertController?](http://stackoverflow.com/questions/36361640/html-file-inside-an-alertcontroller) – JAL Jan 25 '17 at 18:51
  • `UIAlertController` does not support such customizations. Create your own alert or find a 3rd party alert that does. – rmaddy Jan 25 '17 at 18:57
  • Thanks. I created a custom alert and it works (it will need some style adjust, but it works) – Mico Programador Jan 25 '17 at 23:05

3 Answers3

4

I didn't want to add any more classes to my project, so I kept looking for a more direct way to do it. I found this link very helpful.

My final code looks like this:

-(void)viewDidAppear:(BOOL) animated {
    NSString *htmlString = @"<html><body><h1>HTML, baby!</h1><p>Try it.<p>You'll totally<br />love it.<br /><b>Sample Bold text</b></body></html>";
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Welcome"
                                                                     message:htmlString
                                                              preferredStyle:UIAlertControllerStyleAlert];
    NSAttributedString *attributedStr = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding]
               options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
                         NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)}
    documentAttributes:nil error:nil];
    UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
        // OK button tappped.
        [self dismissViewControllerAnimated:YES completion:^{ }];
    }];
    [alert setValue:attributedStr forKey: @"attributedMessage"];
    [alert addAction:defaultAction];
    [self presentViewController:alert animated:true completion:nil];
}

I included the viewDidAppear declaration because I had a typo in mine for a long time which kept the UIAlertController from appearing because the whole function was never being called.

ja928
  • 428
  • 3
  • 16
0

You can access the text fields of UIAlertController using the textFields property. Then you can set an attributed string containing HTML going through the text fields by setting attributedText.

raidfive
  • 6,603
  • 1
  • 35
  • 32
  • A code snip would be very helpful to your already good answer. – ICL1901 Jan 25 '17 at 18:39
  • 4
    How does accessing the text fields allow you to change the alert message to HTML? – rmaddy Jan 25 '17 at 18:55
  • @rmaddy, attributed strings support HTML markup, so by using those you can render HTML within labels. – raidfive Jan 25 '17 at 19:17
  • 2
    I understand attributed strings and HTML. That's not my point. You are suggesting the use of the alert's text fields to show the message. – rmaddy Jan 25 '17 at 19:19
0

Well, as rmaddy sugested, i've created a custom alert using a ViewController.

I've added a ViewController in the StoryBoard, with 75% opacity. Above it, a view with two labels (alert and message) and a button (to close the whole thing). In the associated class, the only code will be:

var alertTitle: String?
var messageContent: String?

@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var messageLabel: UILabel!

@IBOutlet weak var AlertView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.

    AlertView.layer.cornerRadius = 5.0

    let attrStr = try! NSAttributedString(
        data: (messageContent?.data(using: String.Encoding.unicode, allowLossyConversion: true)!)!,
        options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
        documentAttributes: nil)

    titleLabel.text = alertTitle

    messageLabel.lineBreakMode = .byWordWrapping
    messageLabel.numberOfLines = 0
    messageLabel.attributedText = attrStr
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}





@IBAction func closeButtonTapped(_ sender: Any) {

    self.dismiss(animated: true, completion: nil)
}

Basically, this will receive the text that will be shown as title, and the message (which would be HTML).

To use that ViewController, i created a function with this code:

func createAlert(title: String, message: String) {

    let storyBoard = UIStoryboard(name: "Main", bundle: nil)
    let alert = storyBoard.instantiateViewController(withIdentifier: "alert") as! AlertViewController

    alert.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
    alert.modalTransitionStyle = UIModalTransitionStyle.crossDissolve

    alert.alertTitle = title
    alert.messageContent = message

    self.present(alert, animated: true, completion: nil)
}

As far i can tell, it works. Message looks like pure HTML text without style (so i will need to correct that), but it does what i needed.

It's a little strange that Alerts on iOS have not a way to show content from HTML. I think that it can be a nice feature. Anyway, thanks rmaddy for this sugestion. It was easier than i expected.