【问题标题】:iOS UIFont.ByName Exception (Value cannot be null. Parameter name: value)iOS UIFont.ByName 异常(值不能为空。参数名称:值)
【发布时间】:2021-05-19 16:27:14
【问题描述】:

在自定义 Xamarin Forms iOS 渲染器中,我正在从文件加载字体,当我到达 UIFont.FromName 时,它​​会触发下面显示的异常。 font var 是一个有效的 CGFont 实例,fontsize 是一个有效的 nfloat。有什么想法吗?

var font = CGFont.CreateFromProvider(fontDataProvider);
Control.Font = UIFont.FromName(font.FullName, (nfloat)e.NewElement.FontSize);

堆栈跟踪:

System.ArgumentNullException: Value cannot be null.
Parameter name: value
  at UIKit.UILabel.set_Font (UIKit.UIFont value) [0x00011] in /Users/builder/data/lanes/1381/3afb4af5/source/maccore/src/build/ios/native/UIKit/UILabel.g.cs:337 
  at DecryptRenderFont.iOS.DecryptRenderControlRenderer.OnElementChanged (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs`1[TElement] e) [0x00215] 
  at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x00118] in <filename unknown>:0 
  at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.iOS.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00000] in <filename unknown>:0 
  at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x0001b] in <filename unknown>:0 
  at Xamarin.Forms.Platform.iOS.VisualElementPackager.OnChildAdded (Xamarin.Forms.VisualElement view) [0x00000] in <filename unknown>:0 
  at Xamarin.Forms.Platform.iOS.VisualElementPackager.Load () [0x00023] in <filename unknown>:0 
  at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x000cc] in <filename unknown>:0 
  at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.iOS.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00000] in <filename unknown>:0 
  at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x0001b] in <filename unknown>:0 
  at Xamarin.Forms.Platform.iOS.VisualElementPackager.OnChildAdded (Xamarin.Forms.VisualElement view) [0x00000] in <filename unknown>:0 
  at Xamarin.Forms.Platform.iOS.VisualElementPackager.Load () [0x00023] in <filename unknown>:0 
  at Xamarin.Forms.Platform.iOS.PageRenderer.ViewDidLoad () [0x0007d] in <filename unknown>:0 
  at (wrapper managed-to-native) ObjCRuntime.Messaging:IntPtr_objc_msgSendSuper (intptr,intptr)
  at UIKit.UIViewController.get_View () [0x00030] in /Users/builder/data/lanes/1381/3afb4af5/source/maccore/src/build/ios/native/UIKit/UIViewController.g.cs:2667 

【问题讨论】:

    标签: ios xamarin xamarin.ios


    【解决方案1】:

    1) 我将假设您看到的异常堆栈没有显示实际的底层错误,因为它来自Xamarin.iOS 生成的UILabel.g.cs 文件(即自动在https://github.com/xamarin/xamarin-macios 中生成包装器),我个人在跟踪某些低级操作系统异常/抛出时遇到了一些问题,因此显示的异常有点(很多?)误导。

    2) 我将再次假设,因为您说您是“从文件加载字体”,这些字体未注册。假设您通过 CGFont.CreateFromProvider 从应用程序包中的文件(或动态下载)加载这些字体,并且由于它们不存在于 UIAppFonts 键下的 info.plist 中,它们不是自动注册 到 iOS。您需要自己完成这一步:

    NSError error;
    if (!CTFontManager.RegisterGraphicsFont(customFont, out error))
    {
       // error occurred, checkout the contents of the NSError var
    }
    

    在 iOS 字体管理器 (CTFontManager) 注册 CGFont 后,您实际上可以在 UIKit 中使用它们,否则在 iOS 代码内部会有异常... 需要编写一些 ObjC/Swift 来检查它在 Xcode 中查看实际抛出的错误是什么......

    您的字体是否已注册:

    在异常之前但在您的CreateFromProvider 之后,您可以执行以下操作:

    foreach (var familyNames in UIFont.FamilyNames.OrderBy(c => c).ToList())
    {
        D.WriteLine(" * " + familyNames);
        foreach (var familyName in UIFont.FontNamesForFamilyName(familyNames).OrderBy(c => c).ToList())
        {
            D.WriteLine(" *-- " + familyName);
        }
    }
    

    注意:D 只是 using D = System.Diagnostics.Debug;

    我敢打赌,您的字体不在列表中,但在调用 CTFontManager.RegisterGraphicsFont 后,它会在该列表中,并且可以被 UIKit 使用。

    更新:

    有趣的是,使用 基于 Swift 的应用 并且不注册字体不会导致应用崩溃。当然没有显示字体,但是通过UIFont(name: "XXXXX", size: 35) 引用它只是一个无声的失败。

    因此,为了安全起见,我只建议在使用自定义字体时使用一些防御性 try{} catch{}

    【讨论】:

    • 注册字体有效,至少让我通过了那个错误。
    【解决方案2】:

    Xamarin.iOS - 自定义字体

    • iOS 仅支持 .TTF 和 .OTF 字体类型。
    • 将字体添加到“Resources/Fonts/”文件夹(任何文件夹都可以,但让其保持井井有条)。
    • 右键单击添加的字体“属性”,将“复制到输出目录”更改为“始终复制”。
    • 打开 Info.plist 文件并选择视图底部的“Source”。
    • “添加新条目”,选择“应用程序提供的字体”。
    • 输入字体“Fonts/FontName.ttf”的位置。
    • 使用它:lab1.Font = UIFont.FromName("FontName", 20f);

    所有功劳归功于 Mike James - custom-fonts-in-ios

    【讨论】:

      【解决方案3】:

      添加到 Eyal/Mike James 的答案。使用正确的FontName 很重要。如果您打开字体文件信息,您可能会看到文件名与您的 Full Name 不同。

      在下图中,您可以看到文件名是FranklinGothicMedium.otf,但全名是FranklinGothicURW-Med。使用UIFont.FromName([YourFontFullName], 20f);时必须使用全名。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多