I was having issues with text truncating with UIAlertController but that issue is fixed now with:
UILabel.appearance(whenContainedInInstancesOf: [UIAlertController.self]).numberOfLines = 2
This will set ALL UIAlertControllers to numberOfLines = 2
but I only want this set to one specific UIAlertController. How can I achieve this?
My actual code for the UIAlertController:
let sheet = UIAlertController(title: "Location", message: nil, preferredStyle: .actionSheet)
for data in locationListArr {
let displayName = "\(data.locAddr1 ?? "") \(data.locAddr2 ?? "") \(data.locCity ?? "") \(data.locProv ?? "") \(data.locPC ?? "")".uppercased()
let item = UIAlertAction(title: displayName, style: .default) { (action) in
self.locID = data.locID
self.locName = data.locName ?? ""
self.locAddr1 = data.locAddr1 ?? ""
self.locAddr2 = data.locAddr2 ?? ""
self.locCity = data.locCity ?? ""
self.locProv = data.locProv ?? ""
self.locPC = data.locPC ?? ""
self.locationBtn.setTitle(displayName, for: .normal)
}
sheet.addAction(item)
}
present(sheet, animated: true, completion: nil)
UILabel.appearance(whenContainedInInstancesOf: [UIAlertController.self]).numberOfLines = 2
Apple's docs say you shouldn't subclass UIAlertController
, but I just tried it, and you can create an empty subclass of UIAlertController
, and use UILabel.appearance(whenContainedInInstancesOf:)
on that subclass.
Take this example:
// Define a dummy subclass of `UIAlertController`
class FooController: UIAlertController {
}
class ViewController: UIViewController {
let buttonLabels = [
"""
Button1
line2
""",
"""
Button2
line2
""",
"""
Button3
line2
"""
]
@IBAction func handleAlertButton(_ sender: Any) {
// Invoke a normal UIAlertController
presentAlert(type: UIAlertController.self)
}
@IBAction func handleFooButton(_ sender: Any) {
// Invoke a FooController.
presentAlert(type: FooController.self)
}
override func viewDidLoad() {
super.viewDidLoad()
// Tweak the appearance of UILabels in `FooController`s
UILabel.appearance(whenContainedInInstancesOf: [FooController.self]).numberOfLines = 2
}
// This function invokes either a normal `UIAlertController` or a custom subclass of `UIAlertController`.
func presentAlert(type: UIAlertController.Type) {
let sheet = type.init(title: type.description(), message: nil, preferredStyle: .actionSheet)
for buttonTitle in buttonLabels {
let item = UIAlertAction(title: buttonTitle, style: .default) { (action) in
print("Button \(buttonTitle) tapped")
}
sheet.addAction(item)
}
present(sheet, animated: true, completion: nil)
}
The handleFooButton()
IBAction creates a UIAlertController
with multi-line action titles, but the handleAlertButton()
IBAction creates a normal UIAlertController
where the actions have single-line titles. That proves that the line UILabel.appearance(whenContainedInInstancesOf: [FooController.self]).numberOfLines = 2
only sets the appearance of UILabels in the context of the dummy FooController
. It does not prove that there are no adverse side-effects of ignoring the docs and subclassing UIAlertController
.
Given that the subclass of UIAlertController
is completely empty, and only defined in order to give a custom target to UILabel.appearance(whenContainedInInstancesOf)
, this may be safe. I say "may" because Apple explicitly says not to subclass UIAlertController
, and you ignore explicit instructions like that from the docs at your own risk.
Given that risk, you are probably better off creating your own modal view controller that looks and acts like a UIAlertController
(As matt suggests in his comment.) It's not that complicated.