Search code examples
iosswiftright-to-leftarabic-support

UIAlertController not displaying text in center when RTL switch in iOS


I a UIAlertViewController which I use to display a toast. I set the alignment to center, and it works fine. If I switch the language from English to Arabic or vice-versa, the message always aligns to natural left.

func displayToast(vc: UIViewController, message: String, seconds: Double = 2.0, completion: (() -> Void)? = nil) {
    let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.alignment = NSTextAlignment.center
    let messageText = NSMutableAttributedString(
        string: message,
        attributes: [
            NSAttributedString.Key.paragraphStyle: paragraphStyle,
            NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body),
            NSAttributedString.Key.foregroundColor: UIColor.gray
        ]
    )
    alert.setValue(messageText, forKey: "attributedMessage")
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + seconds, execute: {
        alert.dismiss(animated: true, completion: nil)
    })
    alert.modalPresentationStyle = .popover
    if let popoverPresentationController = alert.popoverPresentationController {
        popoverPresentationController.sourceView = vc.view
        popoverPresentationController.sourceRect = vc.view.bounds
        popoverPresentationController.permittedArrowDirections = []
    }
    vc.present(alert, animated: true, completion: completion)
}

How to make alert message align center on RTL switch?


Solution

  • The problem is that this line is totally illegal:

    alert.setValue(messageText, forKey: "attributedMessage")
    

    You are working behind the runtime’s back. Your results will be unpredictable, and your app might be rejected from the App Store.

    If you want control over formatting that UIAlertController doesn’t give you, don’t use UIAlertController. Make a real view controller instead.