UIAlertcontroller set attributed messages
Asked Answered
L

3

21

How we can set Attributed text in UIAlertcontroller as message. My try code As bellow, but it will crash the app.

// create Attributed text

let myAttribute = [NSForegroundColorAttributeName: UIColor(red:122.0/255, green:125.0/255, blue:131.0/255, alpha:1.0),NSFontAttributeName: Constant.flinntRegularFont(15)]
let myAttribute2 = [NSForegroundColorAttributeName: UIColor.blackColor(),NSFontAttributeName: Constant.flinntMediumFont(15)]

let myString = NSMutableAttributedString(string: "You have been unsubscribed from ", attributes: myAttribute)
let myString2 = NSMutableAttributedString(string: self.course.course_name, attributes: myAttribute2)
let myString3 = NSMutableAttributedString(string: "\n\nYour refund will be initiated within one week.", attributes: myAttribute)
let myString4 = NSMutableAttributedString(string: "\n\nFor any help call us on", attributes: myAttribute)
let myString5 = NSMutableAttributedString(string: " 079-4014 9800", attributes: myAttribute2)
let myString6 = NSMutableAttributedString(string: " between 9:30 am to 6:30 pm on Monday to Saturday.\n\nWe will be always here with great deals to share.", attributes: myAttribute)

myString.appendAttributedString(myString2)
myString.appendAttributedString(myString3)
myString.appendAttributedString(myString4)
myString.appendAttributedString(myString5)
myString.appendAttributedString(myString6)

Present UIAlertcontroller Code

let alert = UIAlertController(title: "", message: "Select course", preferredStyle: UIAlertControllerStyle.Alert)
    alert.setValue(myAttribute, forKey: "attributedMessage") // this line make a crash.

    alert.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: { (action) in
        self.delegate?.courseRefundViewControllerCoursrRefunded?(self)
        self.navigationController?.popViewControllerAnimated(true)
    }))
self.presentViewController(alert, animated: true, completion: nil)

Thanks.

enter image description here

Liam answered 23/5, 2017 at 9:4 Comment(2)
Possible duplicate of UIAlertController custom font, size, colorLecithinase
You cannot pass the attributedString to UIAlertController without using the private API.Lecithinase
S
41

You app is crashing because of DataType mismatch.

alert.setValue(<value>, forKey: "attributedMessage")

Here <value> must be an instance of NSMutableAttributedString.

But you are passing myAttribute Which is Dictionary.

It is trying ta call length method but it is not found on Dictionary thats why app is crashing.

Try this:

alert.setValue(myString, forKey: "attributedMessage")
Spinous answered 23/5, 2017 at 9:29 Comment(3)
Thanks @Spinous for your help.Liam
thanks. it's worrisome this is not exposed explicitly and you have to do this blind flight dance in the first place :-[Ley
filed 51171348 with apple to remove the need fo this kludgeLey
M
2

The accepted answer here works as of iOS 15, but if Apple ever changes their private api this would crash without warning. What's ironic is that historically it's when they make this kind of api public that it changes and breaks things like this. Here is a way to use the private api safely:

if
    let property = class_getProperty(type(of: alert), "attributedMessage"),
    let type = property_copyAttributeValue(property, "T"),
    String(cString: type) == #"@"NSAttributedString""#
{
    alert.setValue(myString, forKey: "attributedMessage")
} else {
    alert.message = myString.string
}
Marissamarist answered 17/12, 2021 at 15:55 Comment(0)
K
0

As an alternative to private API you could use https://github.com/AntonPoltoratskyi/NativeUI

pod 'NativeUI/Alert', '~> 1.0'

It is a custom view controller that was implemented from scratch and looks exactly like native UIAlertController.

You could pass either String, NSAttributedString or custom content view.

let viewModel = Alert(
    title: "Your Title",
    message: nil,
    contentView: customView,
    actions: [cancelAction, confirmAction]
)
let alert = AlertViewController(viewModel: viewModel)
present(alert, animated: true)
Keeping answered 5/4, 2020 at 18:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.