GradientBoxView IOS Custom renderer problem with colors

AntoniodelCastilloAntoniodelCastillo ESMember
edited July 2016 in Xamarin.Forms

I'm trying to recreate the gradient background effect from here:
https://forums.xamarin.com/discussion/22440/gradient-as-background-color

But instead of using it as page background I want to use it in a boxView, the problem is that IOS renders the colors into lighter versions, as if it has opacity values under 1 (or similar...)

For the common component I'm extending the boxview class adding it a two Xamarin.Forms.Color properties (StartColor and EndColor):

public class GradientBoxView : BoxView
{
    public Xamarin.Forms.Color StartColor { get; set; }
    public Xamarin.Forms.Color EndColor { get; set; }
}

The custom renderer class for IOS is this:

public class GradientBoxViewRenderer : BoxRenderer 
{
    public override void Draw (CGRect rect)
    {
        base.Draw (rect);
        this.Element.Opacity = 1;
        GradientBoxView box = (GradientBoxView)this.Element;

        CGColor startColor = box.StartColor.ToCGColor();//box.StartColor.AddLuminosity(1).MultiplyAlpha(2).ToCGColor();//
        CGColor endColor = box.EndColor.ToCGColor();//box.EndColor.AddLuminosity(1).MultiplyAlpha(2).ToCGColor();//

        var gradientLayer = new CAGradientLayer();
        //gradientLayer.Opaque = true;
        gradientLayer.Frame = rect;
        gradientLayer.Colors = new CGColor[] { startColor, endColor };
        //NativeView.Opaque = true;
        NativeView.Layer.InsertSublayer (gradientLayer, 0);
    }
}

Searching in the forum I did find someone having a similar issue with IOS topBar colors and the solution was setting "Opaque" to true and "Translucent" to false, but BoxView doesn't seems to have a Translucent property to play with and the "Opaque" one does nothing (at least I cant tell a difference by commenting/uncommenting the lines of my renderer where I play with it...)

Anyone here with the same issue or with any solution?

(I posted this same message as a thread instead as question by mistake, if there is some admin who can delete the one from thread it would be great)

Best Answers

Answers

  • AntoniodelCastilloAntoniodelCastillo ESMember
    edited July 2016

    I found a possible workaround for this, it is not the optimal solution but it works and the final result is quite similar, in case someone came here with the same problem here is what I did (basically I made the original color darker before using it for the gradient):

            public override void Draw(CGRect rect)
            {
                base.Draw(rect);
                this.Element.Opacity = 1;
                GradientBoxView box = (GradientBoxView)this.Element;
    
                CGColor startColor = this.getDarker(box.StartColor);
                CGColor endColor = this.getDarker(box.EndColor);
    
                var gradientLayer = new CAGradientLayer();
                gradientLayer.Frame = rect;
                gradientLayer.Colors = new CGColor[] { startColor, endColor };
                NativeView.Layer.InsertSublayer(gradientLayer, 0);
            }
    
            protected CGColor getDarker(Color _currColor)
            {
                nfloat r, g, b, a;
                r = (nfloat)(_currColor.R - 0.07);
                g = (nfloat)(_currColor.G - 0.07);
                b = (nfloat)(_currColor.B - 0.07);
                a = (nfloat)(_currColor.A);
    
                CGColor retColor = new CGColor(r, g, b, a);
                return retColor;
            }
    

    I know it is a lame solution, but I lack the knowledge to find a different way... I just post it here in case someone finds in the same situation and need "any solution".

    Anyway, if someone knows a better way to solve this, please be my guest...

  • TommyBaggettTommyBaggett USUniversity ✭✭✭

    Hey Antonio,

    I just released XFGloss, a free open source add-on. It adds a "BackgroundGradient" property to the XF ContentPage class and all of the Cell classes as well as several other properties. I will create a task to add the property to the BoxView class soon. I will also try to reproduce what you're doing and see if I can suggest a fix for your code in the meantime.

    Can you take a look at what XFGloss does in the currently supported classes? Let me know if it would work for what you're trying to do with the BoxView class. Thanks!

    Check out https://github.com/tbaggett/xfgloss for details. Its also available as a NuGet package at https://www.nuget.org/packages/Ansuria.XFGloss/.

Sign In or Register to comment.