Xamarin.forms 在Xamarin forms iOS中,定制框架的圆锥体正在修剪

Xamarin.forms 在Xamarin forms iOS中,定制框架的圆锥体正在修剪,xamarin.forms,xamarin.ios,custom-renderer,Xamarin.forms,Xamarin.ios,Custom Renderer,我已经为一个框架创建了一个自定义渲染器,使其仅在两条边上具有圆角。该代码在Android中运行良好,但在iOS中,如果框架的背景颜色为白色,边框颜色为蓝色,则圆角会被修剪,如下图所示 自定义渲染器IOS public class CustomFrameRenderer : FrameRenderer { public override void LayoutSubviews() { base.LayoutSubv

我已经为一个框架创建了一个自定义渲染器,使其仅在两条边上具有圆角。该代码在Android中运行良好,但在iOS中,如果框架的背景颜色为白色,边框颜色为蓝色,则圆角会被修剪,如下图所示

自定义渲染器IOS

public class CustomFrameRenderer : FrameRenderer
    {
        
        public override void LayoutSubviews()
        {
            base.LayoutSubviews();

            UpdateCornerRadius();
        }

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

            if (e.PropertyName == nameof(CustomFrame.CornerRadius) ||
                e.PropertyName == nameof(CustomFrame))
            {
                UpdateCornerRadius();
            }
        }

        // A very basic way of retrieving same one value for all of the corners
        private double RetrieveCommonCornerRadius(CornerRadius cornerRadius)
        {
            var commonCornerRadius = cornerRadius.TopLeft;
            if (commonCornerRadius <= 0)
            {
                commonCornerRadius = cornerRadius.TopRight;
                if (commonCornerRadius <= 0)
                {
                    commonCornerRadius = cornerRadius.BottomLeft;
                    if (commonCornerRadius <= 0)
                    {
                        commonCornerRadius = cornerRadius.BottomRight;
                    }
                }
            }

            return commonCornerRadius;
        }

        private UIRectCorner RetrieveRoundedCorners(CornerRadius cornerRadius)
        {
            var roundedCorners = default(UIRectCorner);

            if (cornerRadius.TopLeft > 0)
            {
                roundedCorners |= UIRectCorner.TopLeft;
            }

            if (cornerRadius.TopRight > 0)
            {
                roundedCorners |= UIRectCorner.TopRight;
            }

            if (cornerRadius.BottomLeft > 0)
            {
                roundedCorners |= UIRectCorner.BottomLeft;
            }

            if (cornerRadius.BottomRight > 0)
            {
                roundedCorners |= UIRectCorner.BottomRight;
            }

            return roundedCorners;
        }

        private void UpdateCornerRadius()
        {
            var cornerRadius = (Element as CustomFrame)?.CornerRadius;
            if (!cornerRadius.HasValue)
            {
                return;
            }

            var roundedCornerRadius = RetrieveCommonCornerRadius(cornerRadius.Value);
            if (roundedCornerRadius <= 0)
            {
                return;
            }

            var roundedCorners = RetrieveRoundedCorners(cornerRadius.Value);

            var path = UIBezierPath.FromRoundedRect(Bounds, roundedCorners, new CGSize(roundedCornerRadius, roundedCornerRadius));
            var mask = new CAShapeLayer { Path = path.CGPath };
            NativeView.Layer.Mask = mask;
            //NativeView.Layer.CornerRadius = 0;
            NativeView.ClipsToBounds = true;
            NativeView.Layer.MaskedCorners = (CoreAnimation.CACornerMask)3;

        }
    }
公共类CustomFrameRenderer:FrameRenderer
{
公共覆盖无效布局子视图()
{
base.LayoutSubviews();
UpdateCornerRadius();
}
受保护的覆盖无效OnElementPropertyChanged(对象发送方,PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(发送方,e);
如果(e.PropertyName==nameof(CustomFrame.CornerRadius)||
e、 PropertyName==nameof(CustomFrame))
{
UpdateCornerRadius();
}
}
//为所有角点检索相同值的一种非常基本的方法
专用双检索通讯器(转弯半径转弯半径)
{
var commonCornerRadius=cornerRadius.TopLeft;
如果(半径为0)
{
圆角|=UIRectCorner.BottomLeft;
}
如果(cornerRadius.BottomRight>0)
{
圆角|=UIRectCorner.BottomRight;
}
返回圆角;
}
私有void UpdateCornerRadius()
{
var cornerRadius=(元素作为CustomFrame)?.cornerRadius;
如果(!cornerRadius.HasValue)
{
回来
}
var roundedCornerRadius=RetrieveCommonCornerRadius(cornerRadius.Value);

如果(roundedCornerRadius遮罩采用一层,并修剪该视觉效果以匹配遮罩

如果一个图层是一个有黑色边框的矩形,而你的遮罩是一个椭圆形

将显示一个椭圆形,其颜色与所遮罩的矩形相同

但它不会使这些矩形边框变圆,只需将它们剪掉即可

您需要做的是构建一个层来替换NativeView.layer

使用圆角矩形,而不使用遮罩


或者直接更改层中已经存在的元素的值。

您可以检查以下代码

  private void UpdateCornerRadius()
    {
        var cornerRadius = (Element as Frame)?.CornerRadius;
        if (!cornerRadius.HasValue)
        {
            return;
        }

        var roundedCornerRadius = RetrieveCommonCornerRadius(cornerRadius.Value);
        if (roundedCornerRadius <= 0)
        {
            return;
        }

        var roundedCorners = RetrieveRoundedCorners(cornerRadius.Value);

        NativeView.Layer.MasksToBounds = true;
        var path = UIBezierPath.FromRoundedRect(Bounds, roundedCorners, new CGSize(roundedCornerRadius, roundedCornerRadius));
        var mask = new CAShapeLayer { Path = path.CGPath };
        mask.Frame = Bounds;
        mask.LineWidth = 1;
        mask.StrokeColor = UIColor.SystemBlueColor.CGColor;  // border color
        mask.FillColor = UIColor.Clear.CGColor;  // bg color , you need to set it as clear otherwise it will cover its child element
        mask.ShadowRadius = 0;
      
        NativeView.Layer.AddSublayer(mask);
      
       // NativeView.Layer.MaskedCorners = (CoreAnimation.CACornerMask)3;
        
    }
private void UpdateCornerRadius()
{
var cornerRadius=(元素作为框架)?.cornerRadius;
如果(!cornerRadius.HasValue)
{
回来
}
var roundedCornerRadius=RetrieveCommonCornerRadius(cornerRadius.Value);

如果(roundedCornerRadius)它现在可以工作了吗?不,我尝试了下面提到的解决方案,它没有考虑角半径,因为它在我这边工作得很好,你能分享你的样品吗,这样我就可以直接在我这边测试它了?