【问题标题】:Using CGContext, how to draw a line which starts with an unpainted dash segment?使用 CGContext,如何绘制一条以未绘制的虚线段开头的线?
【发布时间】:2015-04-09 15:39:30
【问题描述】:

使用 CGContext,以画线段开始绘制虚线很容易:

using (var ctx = UIGraphics.GetCurrentContext())
{
    ctx.BeginPath();
    //... draw a path here
    var pattern = new float[] { 2, 2 };
    ctx.SetLineDash(0, pattern);
    ctx.DrawPath(CGPathDrawingMode.Stroke);
}

这会画出一条看起来像“xx--xx--xx--xx--”的线,其中“x”表示已绘制,“-”表示未绘制。

现在我想画一条以未绘制线段开头的线,即:“--xx--xx--xx--xx”。有没有一种优雅的方法来实现这一目标?例如。通过告诉 iOS 从未绘制的段开始?

在我们的示例中,可以使用相位参数来实现以未绘制线段开头的线:

using (var ctx = UIGraphics.GetCurrentContext())
{
    ctx.BeginPath();
    //... draw a path here
    var pattern = new float[] { 2, 2 };
    ctx.SetLineDash(2, pattern);
    ctx.DrawPath(CGPathDrawingMode.Stroke);
}

但是,对于更复杂的模式(例如{ 2, 4, 3, 7, 5, 6 }),使用相位参数变得更加麻烦。除了相位参数之外,模式可能还需要移动。

总结一下:是否可以在不使用相位参数的情况下优雅地创建以未绘制线段开头的虚线?

注意:代码示例是用 C# (MonoTouch) 编写的,但问题也适用于原生 iOS 代码。

【问题讨论】:

  • 一种笨拙的解决方法可能是用所需颜色绘制一条实线,然后在其顶部绘制一条白色虚线(或背景色)。
  • @user2320861 谢谢,如果背景颜色已知,该建议应该可以正常工作。就我而言,我需要能够在不同的背景(甚至图像等)上画线。所以我真的需要未上漆的段,而不是“上漆”的段。

标签: ios xamarin.ios uikit core-graphics


【解决方案1】:

简单的解决方案

仅使用划线功能,没有相位参数就无法解决给定的问题。可以通过重新排列破折号数组并设置相位来解决。

要从未绘制的段开始,请将最后一个虚线数组条目移到前面,并设置具有相同值的阶段。例如。当需要模式-xx-xx-xx-xx-xx... 时,带有相位0 的破折号数组1, 2 将导致类似x--x--x--x--... 的模式。带有阶段 2 的破折号数组 2, 1 将根据需要导致模式 -xx-xx-xx-xx-xx...

具有自适应模式重复的扩展解决方案

iOS 似乎总是在绘制和未绘制段之间交替,并且在重复 dash 数组时不会重置。所以例如破折号数组1, 2, 1 将产生一个类似于x--x-xx-x--x... 的线条图案。在我们的例子中,我们希望整个模式重复。也就是说,对于给定的破折号数组,线型应该看起来像x--xx--xx--xx...

为此,我们需要确保 dash 数组始终具有偶数个元素。除了重新排序破折号数组和设置相位之外,我们还需要调整和删除元素。有四种情况需要考虑。

1.从绘制的段开始,偶数段。

这里无事可做。按原样使用破折号数组。相位为 0。

2.从未绘制的段开始,偶数段。

将最后一个破折号数组条目移到前面,并设置一个具有相同值的阶段。参考上面的简单例子。

3.从绘制段开始,奇数段。

将最后一个破折号数组条目添加到第一个条目。删除最后一个条目。设置一个等于原始最后一个破折号数组条目的相位。

例如破折号数组1, 2, 1 通常会导致模式x--x-xx-...。相位为 1 的破折号数组 2, 2 导致所需的模式 x--xx--xx--...

4.从未绘制的段开始,奇数段。

将第一个破折号数组条目添加到最后一个条目。删除第一个条目。设置一个等于所有条目的总和减去原始第一个破折号数组条目的相位(这实质上是让模式在接近结尾处开始,正是我们将原始第一个条目添加到最后一个条目的位置)。

例如破折号数组1, 2, 1 通常会导致模式x--x-xx-...。相位为 3 的模式 2, 2 导致所需的模式 -xx--xx--xx...

替代品

使用划线功能的替代方案可能是@user2320861 所描述的替代方案。 @user2320861 建议使用背景颜色在带有图案线的实线上绘制。当背景颜色已知并使用统一的背景时,这应该可以很好地工作。

不同背景(例如图像)的变体可能是设置剪贴蒙版(CGContextClipToMask) 通过绘制图案线。然后可以使用此剪贴蒙版绘制实线。

【讨论】:

    猜你喜欢
    • 2011-01-30
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-22
    • 2010-10-07
    相关资源
    最近更新 更多