问题描述
在自定义 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 异常(值不能为空.参数名称:值)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!