xamarin.forms - Xamarin Forms CustomLabel 在 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
解决方案
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 实时播放器中测试您的应用程序或在表单预览器中检查您的屏幕,因为当您使用其中一种执行环境时,本机资源不可用。
对于 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", "");
}
}
推荐阅读
- python - 从默认字典中获取值
- java - 如何将当前元素嵌入到新元素中并使用 jsoup 更新到文档中
- apache-kafka - Apache Kafka 是否支持在订阅开始时接收每个 ID 的最新消息?
- angular - Angular 6 lombok 用于反应形式,有什么方法可以实现这种行为?
- windows - 以特权非管理员用户身份启动服务,出现拒绝访问错误
- python - 如果在python中将一列作为无传递,如何对数据框中的列求和
- c# - ASP.NET CORE 2.1 Identity 已注册
- apache-spark - 列表上的 Spark 数据帧操作返回 [Ljava.lang.Object;@]
- ios - 如何在swift 3中制作单选按钮
- c++ -
:0:8: 错误:一个声明中有多种类型