UIAlertController custom font does not work on iOS

UIAlertController custom font does not work.

The following code is the ShowActionSheetAsync function, show ActionSheet . At this point I want to change the font of the ActionSheet . I tried several ways, but it did not work. Is there a good solution?

 public Task<bool> ShowActionSheetAsync() { var source = new TaskCompletionSource<bool>(); var alert = new UIAlertController { Title = "title" }; alert.AddAction(UIAlertAction.Create( "button1", UIAlertActionStyle.Default, _ => source.SetResult(true))); alert.AddAction(UIAlertAction.Create( "cancel", UIAlertActionStyle.Cancel, _ => source.SetResult(false))); // [Block 1] var viewController = UIApplication.SharedApplication.KeyWindow.RootViewController; ViewController.PresentViewController(alert, true, delegate { // [Block 2] }); // [Block 3] return source.Task; } 

First try The following code does not work correctly.

  • When I put the code in [Block 1] or [Block 2]

    • It doesn't work at all
  • When I put the code in [Block 3]

    • Applies only to the first display of ActionSheet . From the second time it does not work.

UILabel.AppearanceWhenContainedIn(typeof(UIActionSheet)).Font = UIFont.FromName(StyleResources.MediumFontName, 20);

Second attempt The following code also does not work properly.

  • When I put the code on [Block 2]

    • After displaying the default font for a short time, showing a custom font
  • When I put the code in [Block 3]

    • it only works with the cancel button

FindDescendantViews<UILabel>() is an extension method for UIView and returns all child views of the corresponding type.

 var labels = alert.View.FindDescendantViews<UILabel>(); foreach (var label in labels) { label.Font = UIFont.FromName(StyleResources.MediumFontName, 20); } 
+8
c # ios uialertcontroller
source share
3 answers

UIAlertController UILabels font and color can be set using the KVC key using the attributedTitle key. Use it in [Block 3]

 func changeAlert(alert: UIAlertController, backgroundColor: UIColor, textColor: UIColor, buttonColor: UIColor?) { let view = alert.view.firstSubview().firstSubview() view.backgroundColor = backgroundColor view.layer.cornerRadius = 10.0 // set color to UILabel font setSubviewLabelsToTextColor(textColor, view: view) // set font to alert via KVC, otherwise it'll get overwritten let titleAttributed = NSMutableAttributedString( string: alert.title!, attributes: [NSFontAttributeName:UIFont.boldSystemFontOfSize(17)]) alert.setValue(titleAttributed, forKey: "attributedTitle") let messageAttributed = NSMutableAttributedString( string: alert.message!, attributes: [NSFontAttributeName:UIFont.systemFontOfSize(13)]) alert.setValue(messageAttributed, forKey: "attributedMessage") // set the buttons to non-blue, if we have buttons if let buttonColor = buttonColor { alert.view.tintColor = buttonColor } } func setSubviewLabelsToTextColor(textColor: UIColor, view:UIView) { for subview in view.subviews { if let label = subview as? UILabel { label.textColor = textColor } else { setSubviewLabelsToTextColor(textColor, view: subview) } } } 
+1
source share

I have a solution here. I created a custom AlertThemeConfigurator that recursively goes through all the subqueries that search for UILabels, and then sets the thematic Text attribute for them for the header, message, and various types of actions. Feel free to attribute attribute strings correctly.

 class AlertThemeConfigurator { class func configureAlertViewController(alertController : UIAlertController) { AlertLabelConfigurator.adjustLabels(inView: alertController.view, alertController: alertController) } class AlertLabelConfigurator { class func adjustLabels(inView view : UIView, alertController : UIAlertController) { for subview in view.subviews { if subview is UILabel { adjustLabel((subview as! UILabel), inAlertViewController : alertController) } adjustLabels(inView :subview, alertController : alertController) } } class func adjustLabel(label : UILabel, inAlertViewController alertController : UIAlertController) { if label.text == alertController.title { label.attributedText = attributedTitle(label.text!) } else if label.text == alertController.message { label.attributedText = attributedBody(label.text!) } for action in alertController.actions { if label.text == action.title { switch action.style { case .Default: label.attributedText = attributedDefaultAction(action.title!) case .Cancel: label.attributedText = attributedCancelAction(action.title!) case .Destructive: label.attributedText = attributedDestructiveAction(action.title!) } } } } class func attributedTitle(title : String) -> NSAttributedString { let attributes = [NSFontAttributeName:UIFont(name: "Avenir-Medium", size: 20)!, NSForegroundColorAttributeName : UIColor.greenColor()] return NSAttributedString(string: title, attributes: attributes) } class func attributedBody(title : String) -> NSAttributedString { let attributes = [NSFontAttributeName:UIFont(name: "Avenir-Medium", size: 12)!, NSForegroundColorAttributeName : UIColor.orangeColor()] return NSAttributedString(string: title, attributes: attributes) } class func attributedDefaultAction(title : String) -> NSAttributedString { let attributes = [NSFontAttributeName:UIFont(name: "Avenir-Medium", size: 14)!, NSForegroundColorAttributeName : UIColor.yellowColor()] return NSAttributedString(string: title, attributes: attributes) } class func attributedCancelAction(title : String) -> NSAttributedString { let attributes = [NSFontAttributeName:UIFont(name: "Avenir-Medium", size: 14)!, NSForegroundColorAttributeName : UIColor.purpleColor()] return NSAttributedString(string: title, attributes: attributes) } class func attributedDestructiveAction(title : String) -> NSAttributedString { let attributes = [NSFontAttributeName:UIFont(name: "Avenir-Medium", size: 14)!, NSForegroundColorAttributeName : UIColor.redColor()] return NSAttributedString(string: title, attributes: attributes) } } } 

To present a challenge

  let alert = CustomAlertController(title: "Title", message:"Message" , preferredStyle: UIAlertControllerStyle.ActionSheet) alert.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Default, handler: nil)) presentViewController(alert, animated: true, completion: nil) AlertThemeConfigurator.configureAlertViewController(alert) 
+1
source share

This is not allowed for a subclass or for changing the default settings for the UIAlertController. You need to create a custom view for it.

+1
source share

All Articles