Xamarin Forms CustomLabel在iOS中崩溃

时间:2018-08-07 11:24:31

标签: xamarin.forms xamarin.ios

我有一个自定义标签控件,其中单独的字体被更改为粗体。 从我无法重现的Appstore获得了以下崩溃日志。 崩溃日志指向使用我的自定义控件导航到.xaml。

public class CustomLabelBold : Label
    {
        public CustomLabelBold()
        {
            FontFamily = "Avenir Next";
        }
    }

以下是崩溃日志:

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Triggered by Thread:  0

Thread 0 name:
Thread 0 Crashed:
0   libsystem_kernel.dylib          0x00000001814492ec __pthread_kill + 8
1   libsystem_pthread.dylib         0x00000001815ea288 pthread_kill$VARIANT$mp + 376 (pthread.c:1484)
2   libsystem_c.dylib               0x00000001813b7db0 __abort + 152 (abort.c:128)
3   libsystem_c.dylib               0x00000001813b7d18 abort + 152 (abort.c:99)
4   MyProject                           0x00000001031046e0 print_callback(char const*, int) + 39061216 (runtime.m:1216)
5   MyProject                           0x00000001030ff1a8 monoeg_g_log + 39039400 (goutput.c:125)
6   MyProject                           0x00000001030ba098 major_alloc_object + 38756504 (sgen-marksweep.c:697)
7   MyProject                           0x00000001030dbec4 copy_object_no_checks + 38895300 (sgen-copy-object.h:71)
8   MyProject                           0x00000001030db470 simple_nursery_serial_scan_object + 38892656 (sgen-minor-copy-object.h:250)
9   MyProject                           0x00000001030dbdf0 simple_nursery_serial_drain_gray_stack + 38895088 (sgen-gray.h:191)
10  MyProject                           0x00000001030b390c finish_gray_stack + 38729996 (sgen-gc.c:1099)
11  MyProject                           0x00000001030b29d0 collect_nursery + 38726096 (sgen-gc.c:1807)
12  MyProject                           0x00000001030af388 sgen_perform_collection + 38712200 (sgen-gc.c:2534)
13  MyProject                           0x00000001030a5f00 sgen_alloc_obj_nolock + 38674176 (sgen-alloc.c:257)
14  MyProject                           0x00000001030a639c sgen_alloc_obj + 38675356 (sgen-alloc.c:423)
15  MyProject                           0x000000010307f100 mono_gc_alloc_obj + 38514944 (sgen-mono.c:948)
16  MyProject                           0x0000000100ce46a8 wrapper_managed_to_native_object___icall_wrapper_mono_gc_alloc_obj_intptr_intptr + 104
17  MyProject                           0x0000000100cde564 wrapper_alloc_object_AllocSmall_intptr_intptr + 228
18  MyProject                           0x0000000100fd71c4 Xamarin_Forms_Core_Xamarin_Forms_BindableObject__ctor + 4272580 (.D:\agent\_work\1\s\Xamarin.Forms.Core\BindableObject.cs:1)
19  MyProject                           0x000000010103326c Xamarin_Forms_Core_Xamarin_Forms_VisualElement__ctor + 4649580 (.D:\agent\_work\1\s\Xamarin.Forms.Core\VisualElement.cs:122)
20  MyProject                           0x0000000100fe3bc0 Xamarin_Forms_Core_Xamarin_Forms_View__ctor + 4324288 (.D:\agent\_work\1\s\Xamarin.Forms.Core\View.cs:24)
21  MyProject                           0x000000010100fa9c Xamarin_Forms_Core_Xamarin_Forms_Label__ctor + 4504220 (.D:\agent\_work\1\s\Xamarin.Forms.Core\Label.cs:57)
22  MyProject                           0x00000001018bd5e4 Core_MyProject_Core_CustomControls_CustomLabelBold__ctor + 20

1 个答案:

答案 0 :(得分:0)

Android要求您指定要使用的字体的实际文件名。 如果仅交出字体名称,将导致崩溃。

因此,请确保将FontFamily属性设置为正确的文件名(在您的情况下,定义粗体版本的字体的名称)。

此外,我建议按如下方式修改自定义渲染器中的代码,以防止在指定错误字体时您的应用崩溃:

    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);

        TextView label = (TextView)Control;

        if (e.NewElement?.FontFamily != null)
        {
            Typeface font = null;
            try
            {
                font = Typeface.CreateFromAsset(AndroidApp.Application.Context.Assets, e.NewElement.FontFamily);
            }
            catch (Exception)
            {
                font = Typeface.Default;
            }
            label.Typeface = font;
        }
    }

这将导致您的标签退回到默认字体,而不是整个应用程序崩溃。作为额外的效果,由于使用这些执行环境之一时本机资源不可用,因此它还使您可以在xamarin Live Player中测试您的应用程序或在窗体预览器中检查屏幕。

对于iOS,请确保在info.plist中有一个条目,其中列出了已添加到应用中的所有字体。

<key>UIAppFonts</key>
<array>
    <string>fontawesome.ttf</string>
    <string>OpenSans-Light.ttf</string>
    <string>OpenSans-Bold.ttf</string>
    <string>OpenSans-LightItalic.ttf</string>
    <string>OpenSans-Italic.ttf</string>
    <string>OpenSans-Regular.ttf</string>
    <string>Lato-Bold.ttf</string>
    <string>Lato-Regular.ttf</string>
</array>

还要确保字体文件位于“资源”文件夹中,并且其构建操作设置为“ BundleResource”。奇怪的是,iOS需要将FontFamily属性设置为不带.ttf扩展名的文件名。

我尝试重新创建崩溃,但是没有成功。发生的最糟糕的事情是呈现了默认字体。 即使所有字体都在正确的位置且属性设置为正确的名称,而没有自定义渲染器,字体也根本不会出现。

这来自我用于iOS标签的自定义渲染器:

    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);
        if (e.NewElement != null && e.NewElement.FontFamily != null)
        {
            e.NewElement.FontFamily = e.NewElement.FontFamily.Replace(".ttf", "");
        }
    }