c# - Xamarin.iOS:CAGradientLayer 的圆角边缘模糊

标签 c# iphone xamarin.forms xamarin.ios

为了自定义我的应用程序的外观,我为按钮实现了一个自定义渲染器,在它们上面设置了渐变背景图像。到目前为止,一切正常。

但是,当我设置角半径时,边缘显得非常模糊。我认为这可能是由于屏幕坐标和实际分辨率之间的差异,但是当我应用一个因子(2 或 3)来适应它时,它完全搞砸了形状(同时仍然模糊)。

这是在 iPhone X 上截取的屏幕截图(注意条目和图像的分辨率):

enter image description here

这是生成背景的代码:

private UIImage CreateGradientBackground(Color startColor, Color endColor)
{
    var gradientLayer = new CAGradientLayer();
    if (Control == null)
        return null;
    gradientLayer.Bounds = Control.Bounds;
    gradientLayer.CornerRadius = (Control.Bounds.Width < Control.Bounds.Height) ? 
        Control.Bounds.Width / 2 : 
        Control.Bounds.Height / 2;
    gradientLayer.Colors = new CGColor[] { startColor.ToCGColor(), endColor.ToCGColor() };
    gradientLayer.StartPoint = new CGPoint(0, 0.5);
    gradientLayer.EndPoint = new CGPoint(1, 0.5);

    UIGraphics.BeginImageContext(gradientLayer.Bounds.Size);
    if (UIGraphics.GetCurrentContext() == null)
        return null;
    gradientLayer.RenderInContext(UIGraphics.GetCurrentContext());
    UIImage image = UIGraphics.GetImageFromCurrentImageContext();
    UIGraphics.EndImageContext();

    return image;
}

这是它的应用方式(适用于所有不同的状态):

Control.SetBackgroundImage(gradientBackground, UIControlState.Normal);

有人知道如何解决这个问题吗?

非常感谢!


解决方案(感谢 NickSpag!)

1:在渐变图层上设置合适的内容比例:

gradientLayer.ContentsScale = UIScreen.MainScreen.Scale;

2:获取正确的图像上下文:

UIGraphics.BeginImageContextWithOptions(gradientLayer.Bounds.Size, false, UIScreen.MainScreen.Scale);

最佳答案

我相信这是因为您的 gradientLayer 的 ContentsScale 默认为 1.0,“UIGraphics”图像上下文的比例也是如此。正如 Ken Thomases 在 answer 中 Eloquent 地说的那样更深入地了解 CALayer 绘图行为:“上下文中有一个隐式转换,可以从用户空间(点,或多或少)转换到设备空间(像素)。”

根据 Apple 的 documentation,使用您专门管理的 CALayer,如果它除了默认值 (1.0) 之外还有任何其他内容,您还必须管理该转换。 .目前,您的渐变是以点为单位计算的,但以 1:1 的方式显示在 iPhone X 的像素上,这在那个花哨的屏幕上看起来很模糊。

完成 gradientLayer.EndPoint 设置后,我会添加:

gradientLayer.ContentsScale = UIScreen.MainScreen.Scale;

并为 UIGraphics 图像上下文指定比例,如下所示:

UIGraphics.BeginImageContextWithOptions(gradientLayer.Bounds.Size, false, UIScreen.MainScreen.Scale);

对于 Xamarin.Mac 或 macOS 后代,如下所示。不要相信您需要指定当前以外的上下文:

gradientLayer.ContentsScale = NSScreen.MainScreen.BackingScaleFactor;

关于c# - Xamarin.iOS:CAGradientLayer 的圆角边缘模糊,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48470368/

相关文章:

c# - 如何打破存储库之间的循环依赖

c# - db.savechanges() 中的默认超时值?

C# 库做 fft 和 ifft?

c# - 更改 MVC 中 DateTime 的显示

iphone - iOS 6 View 层次结构噩梦

iphone - 关于发行证书过期的问题?

iphone - iOS:在 LockScreen 中显示当前播放的轨道信息?

c# - 如何在 Xamarin Forms 中触发 float 操作按钮 OnClicked 事件处理程序

c# - Xamarin - 删除 Android 中的 SearchBar 下划线

xaml - Xamarin.Forms 如何在 VisualState 中使用 Xamarin Community Toolkit TouchEffect