iOS UIFont.ByName Exception (Value cannot be null. Parameter name: value)

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

stacktrace:

  • What is the best way to handle response from Alamofire for a TableView in Swift using separate classes?
  • How to launch camera on viewDidLoad with UIImagePickerControllerDelegate?
  • JSONserialization error
  • How to set the opacity/alpha of a UIImage?
  • Check type of class an NSData store?
  • Is there any way to add constraint between a view and the top layout guide in a xib file?
  • 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 
    

    2 Solutions Collect From Internet About “iOS UIFont.ByName Exception (Value cannot be null. Parameter name: value)”

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

    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…

    Are your fonts registered or not:

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

    Note: D is just using D = System.Diagnostics.Debug;

    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.

    Update:

    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.

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

    Xamarin.iOS – Custom Fonts

    • iOS only supports .TTF and .OTF font types.
    • Add the fonts to the ‘Resources/Fonts/’ folder (any folder would do but lets keep it organized).
    • Right click on the added font, ‘Properties’, change ‘Copy to output directory’ to ‘Always copy’.
    • Open the Info.plist file and select ‘Source’ at the bottom of the view.
    • ‘Add new entry’, select ‘Fonts provided by application’.
    • Input the location of the font ‘Fonts/FontName.ttf’.
    • Use it: lab1.Font = UIFont.FromName("FontName", 20f);

    All credit goes to Mike James – custom-fonts-in-ios.