UIAlertController自定义字体在iOS上不起作用

时间:2016-05-24 06:35:38

标签: c# ios xamarin.ios uialertcontroller

UIAlertController自定义字体无效。

以下代码是一个函数ShowActionSheetAsync,显示ActionSheet。 此时,我想更改ActionSheet的字体。我尝试过几种方法,但效果不好。有好的解决方案吗?

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;
}

首次尝试 以下代码无法正常运行。

  • 当我将代码放在[Block 1][Block 2]

    上时
    • 根本不起作用
  • 当我将代码放在[Block 3]

    上时
    • 仅在第一个节目ActionSheet时适用。从第二次起,它不起作用

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

第二次尝试 以下代码也无法正常工作。

  • 当我将代码放在[Block 2]

    上时
    • 显示短时间的默认字体后,显示自定义字体
  • 当我将代码放在[Block 3]

    上时
    • 仅适用于cancel按钮

FindDescendantViews<UILabel>()UIView的扩展方法,并返回所有相应类型的子视图。

var labels = alert.View.FindDescendantViews<UILabel>();
foreach (var label in labels)
{
    label.Font = UIFont.FromName(StyleResources.MediumFontName, 20);
}

3 个答案:

答案 0 :(得分:1)

可以使用UIAlertController密钥通过KVC设置

UILabels attributedTitle字体和颜色。在[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 :(得分:1)

我在这里有解决方案。我创建了一个自定义的AlertThemeConfigurator,它递归地遍历查找UILabels的所有子视图,然后在它们上设置主题的attributesText,用于标题,消息和不同类型的操作。随意适当地设置归因字符串的样式。

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)
        }
    }
}

提出来电话

 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)

答案 2 :(得分:1)

不允许子类化或更改UIAlertController的默认内容。您需要为其创建自定义视图。