buttonrenderer上的渐变颜色不会更新[Xamarin Forms iOS]

时间:2018-11-05 18:23:34

标签: c# xamarin xamarin.forms xamarin.ios

我正在以Xamarin形式创建带有渐变的按钮。我成功制作了它,但是当我稍后在代码中尝试更新其颜色时,UI中什么也没发生。

这是项目的设置方式:

XAML:

<controls:FullyColoredGradient x:Name = "SelectedBackground" StartColor = "Purple" EndColor="Yellow" /> 

如果我随后在代码上稍作改动,请尝试更新这些颜色,如下所示:

SelectedBackground.EndColor = Color.Red;
SelectedBackground.StartColor = Color.Blue;

然后什么也没有发生。它们不会重新着色。

这是我共享代码的外观:

public class FullyColoredGradient : Button
{
    public static readonly BindableProperty StartColorProperty =
    BindableProperty.Create(nameof(StartColor),
    typeof(Color), typeof(FullyColoredGradient),
    Color.Default);

    public Color StartColor
    {
        get { return (Color)GetValue(StartColorProperty); }
        set { SetValue(StartColorProperty, value); }
    }


    public static readonly BindableProperty EndColorProperty =
    BindableProperty.Create(nameof(EndColor),
    typeof(Color), typeof(FullyColoredGradient),
    Color.Default);

    public Color EndColor
    {
        get { return (Color)GetValue(EndColorProperty); }
        set { SetValue(EndColorProperty, value); }
    }
}

这是我的iOS渲染器:

public class TransparentGradientColor_iOS : ButtonRenderer
{
    CGRect rect;
    CAGradientLayer gradientLayer;

    public TransparentGradientColor_iOS() { }
    public override void Draw(CGRect rect)
    {
        base.Draw(rect);
        this.rect = rect;

        FullyColoredGradient rcv = (FullyColoredGradient)Element;
        if (rcv == null)
            return;

        this.ClipsToBounds = true;
        this.Layer.MasksToBounds = true;

        FullyColoredGradient stack = (FullyColoredGradient)this.Element;

        CGColor startColor = stack.StartColor.ToCGColor();
        CGColor endColor = stack.EndColor.ToCGColor();

        #region for Vertical Gradient

        this.gradientLayer = new CAGradientLayer()
        {
            StartPoint = new CGPoint(0, 0.5),
            EndPoint = new CGPoint(1, 0.5)
        };
        #endregion

        gradientLayer.Frame = rect;
        gradientLayer.Colors = new CGColor[] { startColor, endColor };

        NativeView.Layer.InsertSublayer(gradientLayer, 0);
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement == null)
        {
            UpdateColor();
        }
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        UpdateColor();
    }

    void UpdateColor()
    {
        if (gradientLayer != null)
        {
            FullyColoredGradient stack = (FullyColoredGradient)this.Element;

            CGColor startColor = Xamarin.Forms.Color.White.ToCGColor();
            CGColor endColor = Xamarin.Forms.Color.White.ToCGColor();

            gradientLayer.Colors = new CGColor[] { startColor, endColor };
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我已经使用了此自定义渲染器,它将对所有按钮应用渐变(您可以根据需要创建自定义按钮),可以尝试一下:

[assembly: ExportRenderer(typeof(Button), typeof(CustomButtonRendereriOS))]

namespace XYZ.iOS.Renderer
{
  public class CustomButtonRendereriOS : ButtonRenderer
   {
    //To apply gradient background to button
    public override CGRect Frame
    {
        get
        {
            return base.Frame;
        }
        set
        {
            if (value.Width > 0 && value.Height > 0)
            {
                foreach (var layer in Control?.Layer.Sublayers.Where(layer => layer is CAGradientLayer))
                    layer.Frame = new CGRect(0, 0, value.Width, value.Height);
            }
            base.Frame = value;
        }
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement == null)
        {
            try
            {
                    var gradient = new CAGradientLayer();
                    gradient.CornerRadius = Control.Layer.CornerRadius = 5;
                    gradient.Colors = new CGColor[]
                    {
                        UIColor.FromRGB(243, 112, 33).CGColor,
                        UIColor.FromRGB(226, 64, 64).CGColor
                    };
                    var layer = Control?.Layer.Sublayers.LastOrDefault();
                    Control?.Layer.InsertSublayerBelow(gradient, layer);

            }
            catch (Exception ex)
            {


            }

        }
    }

}

您还可以在自定义渲染器的帮助下使用此处所述的渐变堆栈布局/框架,并对其单击事件使用Tap Gesture。 Gradient Button in Xamarin Forms 希望这可以解决您的问题。