Xamarin.forms 在Xamarin forms iOS中,定制框架的圆锥体正在修剪
我已经为一个框架创建了一个自定义渲染器,使其仅在两条边上具有圆角。该代码在Android中运行良好,但在iOS中,如果框架的背景颜色为白色,边框颜色为蓝色,则圆角会被修剪,如下图所示 自定义渲染器IOSXamarin.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
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)它现在可以工作了吗?不,我尝试了下面提到的解决方案,它没有考虑角半径,因为它在我这边工作得很好,你能分享你的样品吗,这样我就可以直接在我这边测试它了?