如何支持Xamarin表单中的辅助功能字体大小?

如何支持Xamarin表单中的辅助功能字体大小?,xamarin,xamarin.forms,Xamarin,Xamarin.forms,例如,我的页面上有一个标签: var label = new Label { Text = "Some text here.", LineBreakMode = LineBreakMode.WordWrap, FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)) }; 如何根据用户的字体大小辅助功能设置增加(或减少)此标签的字体大小?例如,在iOS中,您可以在“设置”>“常规”>“辅助功能”>“大文

例如,我的页面上有一个标签:

var label = new Label
{
    Text = "Some text here.",
    LineBreakMode = LineBreakMode.WordWrap,
    FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label))
};
如何根据用户的字体大小辅助功能设置增加(或减少)此标签的字体大小?例如,在iOS中,您可以在“设置”>“常规”>“辅助功能”>“大文本”下设置设备的字体大小。我相信苹果称之为“动态文本”,这几乎是你的应用程序所必须支持的

这同样适用于我的应用程序中的其他控件(按钮、入口等)


我在iPhone上尝试过这个设置,但它似乎并没有改变我应用程序中的所有内容。有一些东西,如TableView节标题和列表视图单元格正在更改,但我的标准标签和条目等没有更改。

您需要提供从
preferredFontWithTextStyle
返回的
UIFontWithTextStyle
(C#=
UIFont.PreferredFontForTextStyle
)作为标签的使用上下文,按钮、条目等。。。不会为Xamarin.Forms所知

因此,我为一个客户端所做的是将基本呈现器和视图元素子类化,并向这些元素添加一个仅限iOS的属性,以便它们可以定义该控件在UI中如何开始使用的上下文,因此当由iOS呈现时,这些控件将受到动态文本大小调整的约束

iOS 9中定义了六种动态字体类型:

  • UICTFontTextStyleBody
  • UICTFontTextStyleCaption1
  • UICTFontTextStyleCaption2
  • UICTFontTextStyle脚注
  • UICTFontTextStyleHeadline
  • UICTFONTTEXTSTYLE小标题
注意:Xamarin.iOS没有像Swift那样定义常量/枚举(ObjC也没有定义这些),因此它们作为
NSString
传递,请参见下面的示例

示例渲染器: 为名为
BodyLabel
的标签子类设置
UICTFontTextStyleBody

[assembly: ExportRenderer(typeof(BodyLabel), typeof(iOSLabelBodyRenderer))]
namespace Foobar.iOS
{
    public class iOSLabelBodyRenderer : LabelRenderer
    {
        public iOSLabelBodyRenderer() { }

        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);
            if (Control != null)
                Control.Font = UIFont.GetPreferredFontForTextStyle(new NSString("UICTFontTextStyleBody"));
        }
    }
}
[程序集:导出渲染器(typeof(BodyLabel)、typeof(iOSLabelBodyRenderer))]
命名空间Foobar.iOS
{
公共类iOSLabelBodyRenderer:LabelRenderer
{
公共iOSLabelBodyRenderer(){}
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
if(控件!=null)
Control.Font=UIFont.GetPreferredFontForTextStyle(新NSString(“UICTFontTextStyleBody”);
}
}
}
结果:


注意:从技术上讲,您还应该实现
UIContentSizeCategoryDidChangeNotification
通知,以便在用户更改动态字体大小时调整控件大小/使控件无效。

使用@SushiHangover提供的答案中的信息,我能够为iOS实现以下呈现器策略:

为要在其上支持动态文本的每个控件创建渲染器。在我的例子中,这包括标签、按钮和入口。渲染器将
控件.Font
分配给
UIFontDescriptor
,并根据分配给Xamarin Forms控件的
NamedSize
调整
点大小的百分比

例如:

[程序集:导出渲染器(typeof(按钮)、typeof(CustomButtonRenderer))]
命名空间iOS.Controls
{
公共类CustomButtonRenderer:ButtonRenderer
{
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
var view=e.NewElement作为按钮;
if(Control!=null&&view!=null)
{
var descriptor=UIFontDescriptor.PreferredBody;
var pointSize=descriptor.pointSize;
var size=view.FontSize;
if(size==Device.GetNamedSize(NamedSize.Large,typeof(按钮)))
{
点大小*=1.4f;
}
else if(size==Device.GetNamedSize(NamedSize.Small,typeof(按钮)))
{
点大小*=.8f;
}
else if(size==Device.GetNamedSize(NamedSize.Micro,typeof(按钮)))
{
点大小*=.6f;
}
Control.Font=UIFont.FromDescriptor(描述符,点大小);
}
}
}
}
通过基于基本
NamedSize.Default
size的百分比值,您甚至可以通过这种方式动态支持固定字体大小

例如:

[程序集:导出渲染器(typeof(按钮)、typeof(CustomButtonRenderer))]
命名空间iOS.Controls
{
公共类CustomButtonRenderer:ButtonRenderer
{
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
var view=e.NewElement作为按钮;
if(Control!=null&&view!=null)
{
var descriptor=UIFontDescriptor.PreferredBody;
var percent=view.FontSize/Device.GetNamedSize(NamedSize.Default,typeof(按钮));
Control.Font=UIFont.FromDescriptor(描述符,百分比*描述符.PointSize);
}
}
}
}
作为参考,本文提供了完整的iOS实现示例。

。如果将指定给文本元素的
FontSize
属性,则文本现在将使用通过iOS“大文本”设置设置的值进行缩放

例如,这将产生可访问、可伸缩的文本:

<Label
    FontSize="Large"
    LineBreakMode="WordWrap"
    Text="Some text here." />


您是否尝试过手机上的设置?它不工作吗?我打开了设置,但它不工作。让我更新一下我的问题。谢谢。让我玩一下,看看我能想出什么。稍后将更新。可能只是在此处添加“大”不是自动调整字体大小之一。只有标题、副标题、标题、正文和标题被映射到iOS“魔术”字体(来自您链接的PR)。其余的是马普