本文介绍了iOS UIFont.ByName 异常(值不能为空.参数名称:值)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In a custom Xamarin Forms iOS renderer I am loading fonts from files and when I get to UIFont.FromName it thorws the exception shown below. The font var is a valid CGFont instance and fontsize is a valid nfloat. Any ideas?

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

推荐答案

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

1 ) I am going to assume the exception stack you are seeing is not showing the actual underlaying error as it is coming from the Xamarin.iOS generated UILabel.g.cs file (that is a auto-generated wrapper within https://github.com/xamarin/xamarin-macios) and I personally have had a few issues tracing certain low-level OS exceptions/throws and thus the shown exception is a little (a lot?) misleading.

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

2) Again I am going to assume since you said you are "loading fonts from files" that these fonts are not registered. Assuming you are loading these fonts via a CGFont.CreateFromProvider from files in your app bundle (or dynimically downloaded) and since they do not exist in the info.plist under the UIAppFonts key, they are not auto-registered to iOS. You need to do that step yourself:

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 中检查它以查看抛出的实际错误是什么......


After registering the CGFont with the iOS font manager (CTFontManager) you can actually use them within UIKit, otherwise internally there is an exception within iOS code... Would need to write some ObjC/Swift to check it out in Xcode to see what the actual error being thrown is...

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

Somewhere before the exception but after your CreateFromProvider, you can do the following:

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 使用.

I would bet that your font is not in the list, but after a call to CTFontManager.RegisterGraphicsFont it will be in that list and valid to be consumed by UIKit.

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

Interesting note in that using a Swift-based app and not registering the font does not cause a app crash. The font is not shown of course, but referencing it via UIFont(name: "XXXXX", size: 35) is just a silent failure.

所以我只推荐一些防御性的try{} catch{},以确保安全地使用自定义字体.

So I'd just recommend some defensive try{} catch{} around any use of your custom font to be safe.

这篇关于iOS UIFont.ByName 异常(值不能为空.参数名称:值)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 11:14