简体   繁体   English

Xamarin形成iOS渐变框架渲染器

[英]Xamarin forms gradient frame renderer for iOS

i am creating a custom renderer for Xamarin.Forms Frame control to enable extended functionality like gradient background. 我正在为Xamarin.Forms框架控件创建自定义渲染器,以启用诸如渐变背景之类的扩展功能。

for now i got it to work somehow on iOS but i am working on the android version too. 现在我可以在iOS上以某种方式工作,但我也在android版本上工作。

First i tried to override the SetupLayer method as it is in the default frame renderer see here , and add a sublayer there 首先,我尝试覆盖SetupLayer方法,因为它位于默认的帧渲染器中( 请参见此处) ,并在那里添加一个子层

The way i got it to work was to override Draw method and add a sublayer to the frame view and set the frame layer background to UIColor.Clear. 我使它工作的方法是重写Draw方法并向框架视图添加一个子层,并将框架层背景设置为UIColor.Clear。

The issue that i got is that controls i put inside of frame and also the gradient is somehow faded like there is some layer blending stuff going on. 我遇到的问题是,我将控件放置在框架内,并且渐变以某种方式消失了,就像发生了一些图层混合操作一样。 something like .5 opacity. 像.5不透明度。

Any advice how to get the Layer behind (Gradient) fully opaque? 有什么建议如何使后面的图层(渐变)完全不透明?

Am i doing it wrong ? 我做错了吗?

Thanks in advance. 提前致谢。

Update : I had removed unnecessary code from sample for not creating confusion, the issue i am facing is understand how layers blending work in iOS, as the top-layers blend with added gradient layer and look more faded than normal frame. 更新:我已经从示例中删除了不必要的代码,以免造成混乱,我面临的问题是了解图层混合在iOS中的工作方式,因为顶层与添加的渐变图层混合,并且看起来比正常帧更褪色。

 //not working
 private void SetupLayer()
    {  
 *** 
 var gl = new CAGradientLayer
        {
            StartPoint = new CGPoint(0, 0),
            EndPoint = new CGPoint(1, 1),
            Frame = rect,
            Colors = new CGColor[]
            {
                    _gradinetControl.StartColor.ToCGColor(),
                    _gradinetControl.EndColor.ToCGColor()
            },
            CornerRadius = _gradinetControl.CornerRadius
        };

        Layer.BackgroundColor = UIColor.Clear.CGColor;

       Layer.InsertSublayer(gl,0);
***
}

* *

//working but strange fade blending    
public override void Draw(CGRect rect)
    {           
        var gl = new CAGradientLayer
        {
            StartPoint = new CGPoint(0, 0),
            EndPoint = new CGPoint(1, 1),
            Frame = rect,
            Colors = new CGColor[]
            {
                    _gradinetControl.StartColor.ToCGColor(),
                    _gradinetControl.EndColor.ToCGColor()
            },
            CornerRadius = _gradinetControl.CornerRadius
        };

       NativeView.Layer.BackgroundColor = UIColor.Clear.CGColor;
       NativeView.Layer.InsertSublayer(gl,0);           
       base.Draw(rect);
    }

I think exists a plugin for this. 我认为存在一个插件。 You can take a look there: 您可以在这里看看:

XFGloss XFGloss

in XAML 在XAML中

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xfg="clr-namespace:XFGloss;assembly=XFGloss"
             x:Class="XFGlossSample.Views.AboutPage"
             Title="XFGloss Sample App" Padding="10">

    <xfg:ContentPageGloss.BackgroundGradient>
        <xfg:Gradient Rotation="150">
            <xfg:GradientStep StepColor="White" StepPercentage="0" />
            <xfg:GradientStep StepColor="White" StepPercentage=".5" />
            <xfg:GradientStep StepColor="#ccd9ff" StepPercentage="1" />
        </xfg:Gradient>
    </xfg:ContentPageGloss.BackgroundGradient>
    ...
</ContentPage>

In code 在代码中

namespace XFGlossSample.Views
{
    public class AboutPage : ContentPage
    {
        public AboutPage()
        {
            Title = "XFGloss Sample App";
            Padding = 10;

            // Manually construct a multi-color gradient at an angle of our choosing
            var bkgrndGradient = new Gradient()
            {
                Rotation = 150,
                Steps = new GradientStepCollection()
                {
                    new GradientStep(Color.White, 0),
                    new GradientStep(Color.White, .5),
                    new GradientStep(Color.FromHex("#ccd9ff"), 1)
                }
            };

            ContentPageGloss.SetBackgroundGradient(this, bkgrndGradient);

            Content = { ... }
        }
    }
}

Image with the issue 图片有问题

Finally i found a solution on a Xamarin forum post. 最后,我在Xamarin论坛上找到了一个解决方案。 here It seems iOS render colors differently on layers. 在这里 ,iOS似乎在图层上呈现不同的颜色。 the workaround was to remake the cgcolor based on the xamarin forms color. 解决方法是根据xamarin表格颜色重新制作cgcolor。

public class ExtendedFrameRenderer : FrameRenderer
{
  public override void Draw(CGRect rect)
{           
    var gl = new CAGradientLayer
    {
        StartPoint = new CGPoint(0, 0),
        EndPoint = new CGPoint(1, 1),
        Frame = rect,
        Colors = new CGColor[]
        {
                //old
                //_gradinetControl.StartColor.ToCGColor(),
                // _gradinetControl.EndColor.ToCGColor()
                //fix
                ToCGColor(__gradinetControl.StartColor),
                ToCGColor(__gradinetControl.EndColor)
        },
        CornerRadius = _gradinetControl.CornerRadius
    };

   NativeView.Layer.BackgroundColor = UIColor.Clear.CGColor;
   NativeView.Layer.InsertSublayer(gl,0);           
   base.Draw(rect);
}
    public static CGColor ToCGColor(Color color)
    {
        return new CGColor(CGColorSpace.CreateSrgb(), new nfloat[] { (float)color.R, (float)color.G, (float)color.B, (float)color.A });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM