[更新] :我修改了自定义渲染器以处理这种情况。见下文!
在开发Xamrin Forms(Android + iOS)应用程序时,我遇到了带有标签的奇怪行为:如果我将带有空文本的标签放置在Android上可以正常显示,而在iOS上则完全不显示
这是一个简单的例子:
XAML :
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="MyApp.Views.Page1"
xmlns:ctrl="clr-namespace:MyApp.Controls">
<ContentPage.Content>
<StackLayout Spacing="0">
<Label x:Name="LabelOs" Margin="0,20" />
<Label x:Name="Label1" Text="Label1" BackgroundColor="Red" TextColor="White" Margin="0" Padding="0" />
<Label x:Name="Label2" Text="" BackgroundColor="Green" TextColor="White" Margin="0" Padding="0" />
<Label x:Name="Label3" Text="Label3" BackgroundColor="Blue" TextColor="White" Margin="0" Padding="0" />
<ctrl:RRLabel x:Name="Label1Custom" Text="Label1Custom" BackgroundColor="Yellow" Borders="Left,Right,Bottom" Margin="10,50,10,10" />
<ctrl:RRLabel x:Name="Label2Custom" Text="" Borders="Left,Bottom" BackgroundColor="Yellow" Margin="10" />
<ctrl:RRLabel x:Name="Label3Custom" Text="Label3Custom" Borders="Left,Bottom" BackgroundColor="Yellow" Margin="10" />
<Button x:Name="Button1" Text="Set Label2" Clicked="Button1_Clicked" Margin="20,20,0" />
</StackLayout>
</ContentPage.Content>
背后的代码:
private void Button1_Clicked(object sender,EventArgs e)
{
Label2.Text = "Label2";
Label2Custom.Text = "Label2Custom";
}
标签自定义渲染器(仅相关部分):
public override void Draw(CGRect rect)
{
using (CGContext g = UIGraphics.getcurrentContext())
{
base.Draw(rect);
g.SetLineWidth(2);
g.SetStrokeColor(lineColor);
var path = new CGPath();
if ((label.Borders & RRLabel.LabelBorders.Left) == RRLabel.LabelBorders.Left)
path.AddLines(new CGPoint[] { new CGPoint(rect.Left,rect.Top),new CGPoint(rect.Left,rect.Bottom) });
if ((label.Borders & RRLabel.LabelBorders.Bottom) == RRLabel.LabelBorders.Bottom)
path.AddLines(new CGPoint[] { new CGPoint(rect.Left,rect.Bottom),new CGPoint(rect.Right,rect.Bottom) });
if ((label.Borders & RRLabel.LabelBorders.Right) == RRLabel.LabelBorders.Right)
path.AddLines(new CGPoint[] { new CGPoint(rect.Right,rect.Top) });
if ((label.Borders & RRLabel.LabelBorders.Top) == RRLabel.LabelBorders.Top)
path.AddLines(new CGPoint[] { new CGPoint(rect.Right,rect.Top) });
g.AddPath(path);
g.DrawPath(CGPathDrawingMode.Stroke);
}
}
这是该应用在Android上的外观:
在iOS上:
如您所见,标准标签和自定义标签都存在问题:它们的高度均为0,因此不会显示背景。 设置文本后,将正确呈现标准标签,而在自定义标签中,则没有背景和边框。
如果我将标签文本设置为空格,那当然一切都很好,但是我想避免这种情况。
[解决方案] :我设法通过修改自定义渲染器来解决此问题:
共享控件:
public class RRLabel : Label
{
/* ... */
public bool IosForceHeight { get; set; } = true;
}
渲染器:
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (Control != null && e.NewElement != null)
{
/* ... */
if (label.IosForceHeight && label.Text == "") Control.Text = " ";
}
}
protected override void OnElementPropertyChanged(object sender,PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender,e);
/* ... */
if (label.IosForceHeight && e.PropertyName == nameof(RRLabel.Text) && label.Text == "") Control.Text = " ";
}
这样,我可以始终呈现标签,同时在共享控件中保留Text属性的实际值。