【问题标题】:Xamarin Custom ButtonRenderer Text under Image图像下的 Xamarin 自定义 ButtonRenderer 文本
【发布时间】:2016-11-01 13:01:03
【问题描述】:

我正在尝试将标签放在按钮内的图像下方并将其居中。我有一个按钮的自定义渲染器,但由于某种原因,我无法产生所需的输出。代码在 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 自定义渲染器

     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;


        }

    }

期望输出

+-----------+
|           |
|  (Image)  |     
|   Label   |
|           |
+-----------+

【问题讨论】:

    标签: button xamarin xamarin.ios xamarin.forms custom-renderer


    【解决方案1】:

    仅供参考,对于后代,Xamarin.Forms Button 类现在支持属性ContentLayout,其值:上、下、左、右(图像的位置)。因此,对于您想要的输出,您可以使用本机按钮:

    <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.csButtonRenderer.cs

    【讨论】:

      【解决方案2】:

      我会使用 UIButton 支持已经支持 UIImage 以及 Title 文本的事实,您只需调整 ImageEdgeInsetsTitleEdgeInsets 并将 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"
      };
      

      结果是:

      【讨论】:

      • 完美运行。只需要编辑 ImageEdgeInsets 。非常感谢。我真的很感激。
      猜你喜欢
      • 2017-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-30
      • 1970-01-01
      相关资源
      最近更新 更多