Xamarin.Forms - DisplayAlert with Italic font attribute

Hi, I need to display an alert with some part of the message in italics and the other part normal, something like this:

var title = "Title";
var body = "This part in Italic. This part normal.";
Application.Current.MainPage.DisplayAlert(title, body, "OK");

With the part that says: "This part in Italic." in italics and the other one in normal text.

Is it possible to do? If yes, how?

Thanks in advance!

Best Answer

  • Cesar.TomatisCesar.Tomatis US ✭✭
    Accepted Answer

    @RyanDixon said:
    Referencing from https://stackoverflow.com/questions/26460706/uialertcontroller-custom-font-size-color

    Here's what you're going to have to do. Note as said in that post it might get your app rejected? Not sure if that is true though.

    1) Message/Bind through a button click/command to the native iOS project from the Forms project
    2) Create a new UIAlertController setting the style to action sheet
    3) Create a new UIAlertAction setting the title
    4) When presenting, get the representer from the dictionary and set its attributed text to a custom one, with your font style requirements.

    I would probably look over the app store guidelines though to see if modifying the way the alert dialog shows is grounds for rejection.

    Alternatively, you could create an overlay and just set its input transparency and visibility accordingly when you click the button. Although this won't look and feel like an iOS Alert Controller

    Thank you.

    I ended up creating a native alert controller like this:

    void PromptRichTextPopup(string title, string richMessage, string normalMessage, Action onOkCallback, Action onCancel = null) {
                var vc = UIKit.UIApplication.SharedApplication.KeyWindow.RootViewController;
                // take top presented view controller
                while (vc.PresentedViewController != null) {
                    vc = vc.PresentedViewController;
                }
    
                var alertvc = UIAlertController.Create(title, string.Empty, UIAlertControllerStyle.Alert);
                var leftAligned = new NSMutableParagraphStyle();
                leftAligned.Alignment = UITextAlignment.Left;
    
                var colorTitle = new NSAttributedString(str: title, font: UIFont.BoldSystemFontOfSize(18), foregroundColor: Xamarin.Forms.Color.FromHex("#61acad").ToUIColor());
    
                alertvc.SetValueForKey(colorTitle, new NSString("attributedTitle"));
    
                var margin = 5f;
                var height = 30f;
                var width = 256f;
    
                var container = new UIView(new CGRect(margin, margin, width, height * 4));
    
                var message = new NSMutableAttributedString(str: richMessage, font: UIFont.ItalicSystemFontOfSize(14), foregroundColor: UIColor.Black);
                message.Append(new NSMutableAttributedString(str: " " + normalMessage, font: UIFont.SystemFontOfSize(14), foregroundColor: UIColor.Black));
                var lblText = new UILabel(new CGRect(0, -(height / 2), width, height * 2)) { AttributedText = message };
                lblText.LineBreakMode = UILineBreakMode.WordWrap;
                lblText.Lines = 0;
                container.AddSubview(lblText);
    
                var cancel = new UIButton(new CGRect(0, height, width / 2, height * 2));
                cancel.SetTitle("NO", UIControlState.Normal);
                cancel.AddTarget((sender, e) => alertvc.DismissViewController(true, null), UIControlEvent.TouchUpInside);
                cancel.SetTitleColor(UIColor.Blue, UIControlState.Normal);
                if (onCancel != null) {
                    cancel.AddTarget((sender, e) => {
                        onCancel();
                    },
                    UIControlEvent.TouchUpInside);
                }
                container.AddSubview(cancel);
    
                var ok = new UIButton(new CGRect(width / 2, height, width / 2, height * 2));
                ok.SetTitle("YES", UIControlState.Normal);
                Action okAction = async () => {
                    ok.Enabled = false;
                    await uiHelper.RunBlocking(() => {
                        onOkCallback();
                    });
                    alertvc.DismissViewController(true, null);
                };
                ok.SetTitleColor(UIColor.Blue, UIControlState.Normal);
                container.AddSubview(ok);
                ok.AddTarget((sender, e) => {
                    okAction();
                }, UIControlEvent.TouchUpInside);
    
                var controller = new UIViewController();
                controller.View.AddSubview(container);
                alertvc.SetValueForKey(controller, new NSString("contentViewController"));
                vc.PresentViewController(alertvc, true, null);
            }
    

Answers

  • RyanDixonRyanDixon USMember ✭✭✭

    IMO: I would use a plugin like Rg.Popups and make your template manually in this situation.

    Also What platforms do you need this on?

  • Cesar.TomatisCesar.Tomatis USMember ✭✭

    @RyanDixon said:
    IMO: I would use a plugin like Rg.Popups and make your template manually in this situation.

    Also What platforms do you need this on?

    I'm working on xamarin.forms mainly in iOS.
    I'd like to know if there's a way to do this without any 3rd party plugin.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    I'd like to know if there's a way to do this without any 3rd party plugin.

    No. You've outgrown the simplistic capability of the default DisplayAlert.

  • RyanDixonRyanDixon USMember ✭✭✭

    Referencing from https://stackoverflow.com/questions/26460706/uialertcontroller-custom-font-size-color

    Here's what you're going to have to do. Note as said in that post it might get your app rejected? Not sure if that is true though.

    1) Message/Bind through a button click/command to the native iOS project from the Forms project
    2) Create a new UIAlertController setting the style to action sheet
    3) Create a new UIAlertAction setting the title
    4) When presenting, get the representer from the dictionary and set its attributed text to a custom one, with your font style requirements.

    I would probably look over the app store guidelines though to see if modifying the way the alert dialog shows is grounds for rejection.

    Alternatively, you could create an overlay and just set its input transparency and visibility accordingly when you click the button. Although this won't look and feel like an iOS Alert Controller

  • Cesar.TomatisCesar.Tomatis USMember ✭✭
    Accepted Answer

    @RyanDixon said:
    Referencing from https://stackoverflow.com/questions/26460706/uialertcontroller-custom-font-size-color

    Here's what you're going to have to do. Note as said in that post it might get your app rejected? Not sure if that is true though.

    1) Message/Bind through a button click/command to the native iOS project from the Forms project
    2) Create a new UIAlertController setting the style to action sheet
    3) Create a new UIAlertAction setting the title
    4) When presenting, get the representer from the dictionary and set its attributed text to a custom one, with your font style requirements.

    I would probably look over the app store guidelines though to see if modifying the way the alert dialog shows is grounds for rejection.

    Alternatively, you could create an overlay and just set its input transparency and visibility accordingly when you click the button. Although this won't look and feel like an iOS Alert Controller

    Thank you.

    I ended up creating a native alert controller like this:

    void PromptRichTextPopup(string title, string richMessage, string normalMessage, Action onOkCallback, Action onCancel = null) {
                var vc = UIKit.UIApplication.SharedApplication.KeyWindow.RootViewController;
                // take top presented view controller
                while (vc.PresentedViewController != null) {
                    vc = vc.PresentedViewController;
                }
    
                var alertvc = UIAlertController.Create(title, string.Empty, UIAlertControllerStyle.Alert);
                var leftAligned = new NSMutableParagraphStyle();
                leftAligned.Alignment = UITextAlignment.Left;
    
                var colorTitle = new NSAttributedString(str: title, font: UIFont.BoldSystemFontOfSize(18), foregroundColor: Xamarin.Forms.Color.FromHex("#61acad").ToUIColor());
    
                alertvc.SetValueForKey(colorTitle, new NSString("attributedTitle"));
    
                var margin = 5f;
                var height = 30f;
                var width = 256f;
    
                var container = new UIView(new CGRect(margin, margin, width, height * 4));
    
                var message = new NSMutableAttributedString(str: richMessage, font: UIFont.ItalicSystemFontOfSize(14), foregroundColor: UIColor.Black);
                message.Append(new NSMutableAttributedString(str: " " + normalMessage, font: UIFont.SystemFontOfSize(14), foregroundColor: UIColor.Black));
                var lblText = new UILabel(new CGRect(0, -(height / 2), width, height * 2)) { AttributedText = message };
                lblText.LineBreakMode = UILineBreakMode.WordWrap;
                lblText.Lines = 0;
                container.AddSubview(lblText);
    
                var cancel = new UIButton(new CGRect(0, height, width / 2, height * 2));
                cancel.SetTitle("NO", UIControlState.Normal);
                cancel.AddTarget((sender, e) => alertvc.DismissViewController(true, null), UIControlEvent.TouchUpInside);
                cancel.SetTitleColor(UIColor.Blue, UIControlState.Normal);
                if (onCancel != null) {
                    cancel.AddTarget((sender, e) => {
                        onCancel();
                    },
                    UIControlEvent.TouchUpInside);
                }
                container.AddSubview(cancel);
    
                var ok = new UIButton(new CGRect(width / 2, height, width / 2, height * 2));
                ok.SetTitle("YES", UIControlState.Normal);
                Action okAction = async () => {
                    ok.Enabled = false;
                    await uiHelper.RunBlocking(() => {
                        onOkCallback();
                    });
                    alertvc.DismissViewController(true, null);
                };
                ok.SetTitleColor(UIColor.Blue, UIControlState.Normal);
                container.AddSubview(ok);
                ok.AddTarget((sender, e) => {
                    okAction();
                }, UIControlEvent.TouchUpInside);
    
                var controller = new UIViewController();
                controller.View.AddSubview(container);
                alertvc.SetValueForKey(controller, new NSString("contentViewController"));
                vc.PresentViewController(alertvc, true, null);
            }
    
Sign In or Register to comment.