Xamarin - 在绝对布局中带有文本和图像的按钮导致 mis-aligned 个元素

Xamarin - Button with text and image in absolute layout results in mis-aligned elements

我正在尝试在 Xamarin Forms cross-platform 应用程序(iOS 和 Android)中创建一个按钮,其中该按钮既有文本又有图像。 XAML 非常简单:

<AbsoluteLayout ...>
   <Labels and backgrounds and such>
   <Button x:Name="HomeButton2" TranslationX="6" TranslationY="100"
     BackgroundColor="#efeff4" TextColor="#4a4a4a"
     WidthRequest="58" HeightRequest="76"
     ContentLayout="Top,5" 
     Image="TaskBar_Assets_HomeButtonIcon.png" Text="Home"
     Clicked="HomeButton_Clicked" />
</AbsoluteLayout>

但是我在 iPad 上得到的是一个按钮,图像和文本都奇怪地被推到了一边:

(源图像 "TaskBar_Assets_HomeButtonIcon.png" 为 47 x 44,因此它应该适合整个按钮区域)

我能找到的使它看起来更好的唯一方法是基于 Button 创建一个自定义控件,然后我发现底层 UIButton 的几个属性看起来很奇怪:

Control.ImageView.Frame全为零:

Control.ImageView = <UIImageView: 0x12df52940; frame = (0 0; 0 0);
   clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO;
   layer = <CALayer: 0x173623180>>

Control.ImageEdgeInsets 和 .TitleEdgeInsets 看起来很奇怪(右 + 左似乎没有为图像或文本留下 space):

Control.ImageEdgeInsets = {-8.9501953125, 20.33935546875, 8.9501953125, -20.33935546875}
Control.TitleEdgeInsets = {22, -23.5, -22, 23.5}

我正在做的是调整 Control.ImageEdgeInsets 以便 Control.ImageEdgeInsets.Left 等于(按钮宽度减去图像宽度)的一半并设置 Control.ImageEdgeInsets .归零的权利(除了它有效之外没有特别的原因)

然后弄清楚要设置什么 Control.TitleEdgeInsets 是通过反复试验完成的,我最终得到了与 "Home" 文本宽度(41 像素)相关的值:

Control.ImageEdgeInsets updated to {-8.9501953125, 5.5, 8.9501953125, 0}
Control.TitleEdgeInsets updated to {22, -50, -22, -9}

这会产生合理的按钮外观:

虽然看起来我需要做更多的试验和错误才能使文本 "Home" 真正居中。

但为什么我需要经历这一切?为什么按钮不能首先正确显示文本和图像?

如果我确实必须经历所有这些,为什么 ImageEdgeInsets 和 TitleEdgeInsets 的 Left & Right 值如此不同?

我读过的大多数关于按钮图像的文章都建议您在网格中使用图像和标签构建您自己的图像,并使用手势识别器来处理点击。

您也可以在网格中尝试按钮和图像。

使用边距调整位置。

我尽量避免绝对布局。

这是来自 Xamarin.Froms 的 ButtonRenderer 源代码。如果您将 ContentLayout 设置为 Top,下面的代码将是 运行:

void ComputeEdgeInsets(UIButton button, Button.ButtonContentLayout layout)
{
    ...
    var horizontalImageOffset = labelWidth / 2;
    var horizontalTitleOffset = imageWidth / 2;

    ...
    button.ImageEdgeInsets = new UIEdgeInsets(-imageVertOffset, horizontalImageOffset, imageVertOffset, -horizontalImageOffset);
    button.TitleEdgeInsets = new UIEdgeInsets(titleVertOffset, -horizontalTitleOffset, -titleVertOffset, horizontalTitleOffset);
}

如代码所示,image 的左偏移量为 horizontalImageOffsetlabelWidth / 2title 的左偏移量是 horizontalTitleOffsetimageWidth / 2

所以,文字越宽,图片的左偏移量越大。图片越宽,文字的左偏移量越大

编辑:

在原生 iOS 中,默认布局类似于左图:图像在左侧,标签在右侧。在 Xamarin for Top 设置中,Xamarin 将 Image 向上和向右移动,将 Label 向下和向左移动,使它们像右图一样。我画了这张图,希望大家看清楚。