我正在尝试将Label放在按钮内的图像下并居中。我有一个按钮的自定义渲染器,但由于某种原因,我无法生成所需的输出。代码在C#Xamarin中。
XAML代码:
<Controls:ExtendedButton
VerticalOptions="EndAndExpand"
HorizontalOptions="CenterAndExpand"
x:Name="search"
Text="Search"
Image="Completed.png"
IsEnabled="{Binding IsLoading}"
Command="{Binding SearchCommand}"
WidthRequest ="120"
HeightRequest ="120"
TextColor="#FFFFFF"
>
</Controls:ExtendedButton>
C#iOS CustomRenderer
public class ExtendedButtonRenderer : ButtonRenderer
{
UIButton btn;
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
btn = (UIButton)Control;
CGRect imageFrame = btn.ImageView.Frame;
imageFrame.Y = 0;
imageFrame.X = (btn.Frame.Size.Width / 2) - (imageFrame.Size.Width / 2 );
btn.ImageView.Frame = imageFrame;
var labelSize = new NSString(btn.TitleLabel.Text).
GetBoundingRect(
new CGSize(btn.Frame.Width, float.MaxValue),
NSStringDrawingOptions.UsesLineFragmentOrigin,
new UIStringAttributes() { Font = UIFont.SystemFontOfSize(8) },
null);
CGRect titleLabelFrame = new CGRect(labelSize.X, labelSize.Y, labelSize.Width, labelSize.Height);
titleLabelFrame.X = (btn.TitleLabel.Frame.Size.Width / 2) - (labelSize.Width / 2);
titleLabelFrame.Y = (btn.ImageView.Frame.Y ) + (btn.ImageView.Frame.Size.Height) + 20;
btn.TitleLabel.Frame = titleLabelFrame;
}
}
DesiredOutput
+-----------+
| |
| (Image) |
| Label |
| |
+-----------+
答案 0 :(得分:9)
仅供参考,对于后代,Xamarin.Forms
按钮类支持属性ContentLayout
现在具有值:顶部,底部,左侧,右侧(图像的位置)。因此,对于您想要的输出,您可以使用原生Button:
<Button
ContentLayout="Top"
VerticalOptions="EndAndExpand"
HorizontalOptions="CenterAndExpand"
x:Name="search"
Text="Search"
Image="Completed.png"
IsEnabled="{Binding IsLoading}"
Command="{Binding SearchCommand}"
WidthRequest ="120"
HeightRequest ="120"
TextColor="#FFFFFF"
/>
我无法记住我在哪里找到此信息,但请参阅Button.cs和ButtonRenderer.cs
答案 1 :(得分:2)
我会使用UIButton
支持已经支持UIImage
以及Title
文字的事实,您只需要调整ImageEdgeInsets
和TitleEdgeInsets
以及设置为x / y对齐到中心。
public class CenterImageButtonRenderer : ButtonRenderer
{
public CenterImageButtonRenderer() { }
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
if (Control != null)
{
Control.VerticalAlignment = UIControlContentVerticalAlignment.Center;
Control.HorizontalAlignment = UIControlContentHorizontalAlignment.Center;
#if DEBUG
// Set the border so we can see button bounds on a white background for testing alignment
Control.Layer.CornerRadius = 15;
Control.Layer.BorderWidth = 5;
Control.Layer.BorderColor = UIColor.Red.CGColor;
#endif
// The button image is not availabe due to lazy load, so we load "again", get the bounds and dispose of it... :-(
var uiImage = UIImage.FromFile(((Button)e.NewElement).Image.File);
var lineHeight = Control.TitleLabel.Font.LineHeight;
Control.ImageEdgeInsets = new UIEdgeInsets(-lineHeight, uiImage.Size.Width + (uiImage.Size.Width / 2), 0, 0);
Control.TitleEdgeInsets = new UIEdgeInsets(uiImage.Size.Height, -uiImage.Size.Width, 0, 0);
uiImage.Dispose();
}
}
}
}
所以假设:
var button = new CenterImageButton
{
Text = "StackOverflow",
Image = "so.png"
};
结果是: