设置 CAShapeLayer lineWidth 小于 1

S.J*_*S.J 1 objective-c cashapelayer ios uibezierpath

在上面的屏幕截图中,有两行:

  1. 实线只是UIView高度为 1px 的线
  2. 使用此代码创建虚线

- (void)viewDidAppear:(BOOL)animated {
    CAShapeLayer *line = [CAShapeLayer layer];
    UIBezierPath *linePath=[UIBezierPath bezierPath];

    [linePath moveToPoint:CGPointMake(0, 107)];
    [linePath addLineToPoint:CGPointMake(self.view.frame.size.width, 107)];

    line.lineWidth = 0.5;
    line.path=linePath.CGPath;
    line.fillColor = [[UIColor blackColor] CGColor];
    line.strokeColor = [[UIColor blackColor] CGColor];

    [line setLineJoin:kCALineJoinRound];
    [line setLineDashPattern: [NSArray arrayWithObjects:[NSNumber numberWithInt:10], [NSNumber numberWithInt:5],nil]];

    [[self.view layer] addSublayer:line];
}
Run Code Online (Sandbox Code Playgroud)

为什么UIView1 像素 ( 1.0) 的高度小于虚线的0.5高度?

我希望虚线和实线一样细。

Ham*_*ish 5

当您说UIView高度为 1px 时,您实际上是指 1px 吗?

\n\n

UIKit 中的大小(分别为lineWidth和)以点为单位,而不是像素。单个点相当于 1x 显示器上的 1 个像素、2x 显示器上的 2 个像素和 3x 显示器上的 3 个像素。*frameCAShapeLayerUIView

\n\n

因此,如果您想要以点为单位的单个像素的大小 - 您会想要

\n\n
1.0/[UIScreen mainScreen].scale\n
Run Code Online (Sandbox Code Playgroud)\n\n

您的图像中似乎存在的问题是您将您的框架原点UIView与您的UIBezierPath. 这些并不相同。框架原点代表\xe2\x80\x94的顶部UIView,而线条代表路径的中心。

\n\n

因此,您需要将线条位置向下偏移其宽度的一半 - 这会将其与像素的中心对齐,从而允许在单个像素上渲染笔画。**

\n\n

像这样的事情应该达到您想要的结果:

\n\n
CGFloat pixelWidth = 1.0/[UIScreen mainScreen].scale;\n\nUIView* v = [[UIView alloc] initWithFrame:(CGRect){0, 50, self.view.frame.size.width, pixelWidth}];\nv.backgroundColor = [UIColor redColor];\n[self.view addSubview:v];\n\nUIBezierPath* p = [UIBezierPath bezierPath];\n[p moveToPoint:(CGPoint){0, 50+(pixelWidth*0.5)}];\n[p addLineToPoint:(CGPoint){self.view.frame.size.width, 50+(pixelWidth*0.5)}];\n\nCAShapeLayer* s = [CAShapeLayer layer];\ns.contentsScale = [UIScreen mainScreen].scale; // ensures the CAShapeLayer renders its contents at the logical scale of the screen\ns.frame = self.view.bounds;\ns.path = p.CGPath;\ns.fillColor = [UIColor clearColor].CGColor;\ns.strokeColor = [UIColor greenColor].CGColor;\ns.lineWidth = pixelWidth;\ns.lineDashPattern = @[@10, @10];\n[self.view.layer addSublayer:s];\n
Run Code Online (Sandbox Code Playgroud)\n\n

生成以下内容(在 iPhone 6 上):

\n\n

在此输入图像描述

\n\n
\n\n

*iPhone 6 Plus 的行为略有不同 - 其物理显示屏的比例 (~2.6x) 与逻辑比例 (3x) 不匹配。

\n\n

因此,您在其中进行的任何绘图都可能导致像素出血,因为它会按比例缩小以进行显示。您可以解决这个问题,但这需要深入研究 Open GL 或 Metal来进行绘图。

\n\n

另请参阅此处,了解每部 iPhone 如何呈现其内容的详细概述。

\n\n
\n\n

**在 2 倍显示屏上,您可能需要将线条的位置额外偏移 0.25 个点,以防止像素渗漏(因为您的线条将位于像素边界上),正如 Andrea 所说

\n