【问题标题】:Gradient color on buttonrenderer does not update [Xamarin Forms iOS]buttonrenderer 上的渐变颜色不更新 [Xamarin Forms iOS]
【发布时间】:2018-11-06 13:52:36
【问题描述】:

我正在 Xamarin 表单中创建一个带有渐变的按钮。我成功制作了它,但是当我稍后在代码中尝试更新其颜色时,UI 中没有任何反应。

这是项目的设置方式:

XAML:

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

如果我稍后在代码中做一个 void 并尝试像这样更新这些颜色:

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 };
        }
    }
}

【问题讨论】:

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


    【解决方案1】:

    我用过这个自定义渲染器,它会对所有按钮应用渐变(如果你愿意,你可以创建自定义按钮),你可以试试这个:

    [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)
                {
    
    
                }
    
            }
        }
    
    }
    

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

    【讨论】:

    • 如何从我的共享代码中应用此按钮的开始/结束颜色?
    • @CarlosRodrigez 将您的颜色代码转换为 RGB 格式并在上面的渲染器中应用它来代替:gradient.Colors = new CGColor[] { UIColor.FromRGB(243, 112, 33).CGColor, UIColor.FromRGB(226, 64, 64).CGColor };
    • 但我想在我的共享代码中执行此操作。因此,如果我将 x:name 添加到我的控件中,那么在代码中我希望能够实时更改它。现在目前它不起作用。我也尝试使用“xamarin 表单中的渐变按钮”示例代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-06
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多