【问题标题】:Set a default font for whole iOS app in Xamarin.iOS?在 Xamarin.iOS 中为整个 iOS 应用设置默认字体?
【发布时间】:2020-09-07 13:49:18
【问题描述】:

我可以像这样为标签、条目等(Xamarin.Forms UI 字段)启用字体...

           <Style TargetType="Label">
                <Setter Property="FontFamily">
                    <Setter.Value>
                        <OnPlatform x:TypeArguments="x:String">
                            <On Platform="iOS" Value="Montserrat_Regular" />
                            <On Platform="Android" Value="Montserrat_Regular.ttf#Montserrat_Regular" />
                        </OnPlatform>
                    </Setter.Value>
                </Setter>
            </Style>

但它不会为对话框的标题和内容应用字体,在选择器中列出更多类似的地方(内部 iOS UI 字段)。

我覆盖了android的默认字体来实现上述问题,但问题出在iOS上,我在C#中找不到任何解决方案。 在objective-c & swift中有很多解决方案。

Objective-c Solution

Swift 5 solution

Another Solution

有人可以帮我转换这些代码或提供任何其他解决方案吗?

编辑-

对话框是特定于设备的,Xamarin.Forms 代码不能单独在上面工作。

iOS 对话框 -

Device.BeginInvokeOnMainThread( () => 
            {
                UIAlertController alert = UIAlertController.Create(title, message, UIAlertControllerStyle.Alert);
                alert.AddAction(UIAlertAction.Create(cancel, UIAlertActionStyle.Cancel, a => task.SetResult(false)));
                alert.AddAction(UIAlertAction.Create(ok, UIAlertActionStyle.Default, a => task.SetResult(true)));
                UIViewController vc = GetViewController(UIApplication.SharedApplication.KeyWindow.RootViewController);
                if (TargetIdiom.Tablet == Device.Idiom)
                {
                    vc.ModalPresentationStyle = UIModalPresentationStyle.Popover;
                }
                vc.PresentModalViewController(alert, true);
            });

带有字体修复的 Android 对话框 -

Device.BeginInvokeOnMainThread( () =>
            {
                AlertDialog dialog = new AlertDialog.Builder(Forms.Context, Resource.Style.Base_Animation_AppCompat_Tooltip).SetTitle(title).SetMessage(content).SetPositiveButton(ok, delegate { task.SetResult(true); })
                .SetNegativeButton(cancel, delegate { task.SetResult(false); }).Show();
                TextView textView = (TextView)dialog.FindViewById(Android.Resource.Id.Message);
                textView.SetTypeface(Typeface.CreateFromAsset(Forms.Context.Assets, "Montserrat_Regular.ttf"), TypefaceStyle.Normal);
                var _buttonOK = (Button)dialog.FindViewById(Android.Resource.Id.Button1);
                _buttonOK.SetTypeface(Typeface.CreateFromAsset(Forms.Context.Assets, "Montserrat_Regular.ttf"), TypefaceStyle.Normal);
                var _buttonCancel = (Button)dialog.FindViewById(Android.Resource.Id.Button2);
                _buttonCancel.SetTypeface(Typeface.CreateFromAsset(Forms.Context.Assets, "Montserrat_Regular.ttf"), TypefaceStyle.Normal);
            });

【问题讨论】:

    标签: c# ios xamarin xamarin.forms xamarin.ios


    【解决方案1】:

    您可以创建一个Custom Label Renderer 来实现这一点。

    在 iOS 解决方案中创建 CustomLabelRenderer:

    [assembly: ExportRenderer(typeof(Label), typeof(CustomLabelRenderer))]
    namespace XamarinTableView.iOS
    {
        public class CustomLabelRenderer: LabelRenderer
        {
            protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
            {
                base.OnElementChanged(e);
                Control.Font = UIFont.FromName("Montserrat-Regular", (nfloat)Element.FontSize);
            }
        }
    }
    

    您将看到typeof(Label),这意味着它将适用于iOS设备中的所有Xamarin Forms标签。

    ===============================更新================ =================

    我已经检查了本地站点并使其适用于UILable。您需要在iOS解决方案中正确添加Montserrat-Regular.ttf文件。

    例如:

    并且还需要在info.plist中添加这个.ttf如下:

    <key>UIAppFonts</key>
    <array>
        <string>Montserrat-Regular.ttf</string>
    </array>
    

    然后渲染器代码将起作用。

    另外,您可以使用typeof(CustomLabel)对特殊Label使用特效。

    ==================================更新#2=========== ======================

    如果需要为 UIAlertController 工作,请尝试以下方式。但是iOS中无法修改Button的字体,只对Title和Message有效。

    Device.BeginInvokeOnMainThread(() => 
    {
        UIAlertController alert = UIAlertController.Create(title, message, UIAlertControllerStyle.Alert);
        var titleAttributedString = new NSAttributedString(title,
            new CTStringAttributes()
            {
                ForegroundColorFromContext = true,
                Font = new CTFont("Montserrat-Regular", 24)
            });
        alert.SetValueForKey(titleAttributedString, new NSString("attributedTitle"));
        var messageAttributedString = new NSAttributedString(message,
            new CTStringAttributes()
            {
                ForegroundColorFromContext = true,
                Font = new CTFont("Montserrat-Regular", 24)
            });
        alert.SetValueForKey(messageAttributedString, new NSString("attributedMessage"));
        UIAlertAction cancleAction = UIAlertAction.Create("Cancle", UIAlertActionStyle.Cancel, a => Console.WriteLine("cancle"));
        alert.AddAction(cancleAction);
        UIAlertAction okAction = UIAlertAction.Create("OK", UIAlertActionStyle.Cancel, a => Console.WriteLine("OK"));
        alert.AddAction(okAction);
        UIViewController vc = GetViewController(UIApplication.SharedApplication.KeyWindow.RootViewController);
        if (TargetIdiom.Tablet == Device.Idiom)
        {
            vc.ModalPresentationStyle = UIModalPresentationStyle.Popover;
        }
        vc.PresentModalViewController(alert, true);
    });
    

    效果:

    【讨论】:

    • 我会试试这个并让你知道,但我想这不是解决方案,因为我为 android 扩展 LabelRenderer 以设置字体做了同样的事情。它只改变了标签组件的字体,但实际上,android的对话框使用TEXTVIEW作为消息部分,而不是标签,所以对话框的字体没有改变。这同样适用于以编程方式创建的自定义列表,LabelRenderer 无法为其更改字体
    • 其实我对 iOS 不太了解,所以我知道 iOS 的对话框和列表中使用了哪些组件...这就是我为 Android 所做的,stackoverflow.com/a/63706206/12768925
    • @Blu Okey,我已经看到你更新的问题,我会检查一下。
    • 谢谢,如果您发现任何更新,请告诉我 :)
    • @Blu 我已经更新了答案,你有时间可以试试。
    【解决方案2】:

    你不能覆盖默认字体,你现在需要在单个组件上设置字体,如果我找到更好的解决方案,我会告诉你

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-01
      • 2014-02-09
      • 2013-04-30
      • 2021-10-07
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多