首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将CAShapeLayer lineWidth设置为小于1

将CAShapeLayer lineWidth设置为小于1
EN

Stack Overflow用户
提问于 2016-04-05 10:21:07
回答 2查看 1.8K关注 0票数 1

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

  1. 实线只是一个高度为1 1px的UIView
  2. 虚线是使用以下代码创建的。
代码语言:javascript
复制
- (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];
}

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-05 10:42:03

当你说UIView的高度是1px时,你的意思是1px吗?

UIKit ( lineWidthframe分别为CAShapeLayerUIView )中的尺寸用点,而不是像素测量。一个点在1x显示器上相当于1个像素,在一个2x显示器上相当于2个像素,在3x显示器上相当于3个像素。

因此,如果你想要点上一个像素的大小-你会想

代码语言:javascript
复制
1.0/[UIScreen mainScreen].scale

您的图像中似乎存在的问题是,您混淆了UIView的帧来源和UIBezierPath的线条。这可不一样。框架原点代表您的UIView的顶部-而线代表您的路径的中心。

因此,您将希望将直线位置向下偏移其宽度的一半--这将使其与像素的中心对齐,从而允许在单个像素上呈现笔画。

这样的应该可以达到您想要的结果:

代码语言:javascript
复制
CGFloat pixelWidth = 1.0/[UIScreen mainScreen].scale;

UIView* v = [[UIView alloc] initWithFrame:(CGRect){0, 50, self.view.frame.size.width, pixelWidth}];
v.backgroundColor = [UIColor redColor];
[self.view addSubview:v];

UIBezierPath* p = [UIBezierPath bezierPath];
[p moveToPoint:(CGPoint){0, 50+(pixelWidth*0.5)}];
[p addLineToPoint:(CGPoint){self.view.frame.size.width, 50+(pixelWidth*0.5)}];

CAShapeLayer* s = [CAShapeLayer layer];
s.contentsScale = [UIScreen mainScreen].scale; // ensures the CAShapeLayer renders its contents at the logical scale of the screen
s.frame = self.view.bounds;
s.path = p.CGPath;
s.fillColor = [UIColor clearColor].CGColor;
s.strokeColor = [UIColor greenColor].CGColor;
s.lineWidth = pixelWidth;
s.lineDashPattern = @[@10, @10];
[self.view.layer addSublayer:s];

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

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

因此,您在其中所做的任何绘图都是会导致像素出血,因为它会被缩小以显示。你可以绕开它,但它是涉及深入到开放式GL或金属做你的绘画。

也见这里,以了解每个iPhone如何呈现它们的内容。

**在2x显示器上,您还可能需要将直线的位置偏移0.25个点,以防止像素流血(因为您的线位于像素边界上),正如安德里亚所说

票数 5
EN

Stack Overflow用户

发布于 2016-04-05 10:41:58

0.5点将转化为:

  • 1.5px在@3x视网膜显示器上
  • @2x视网膜显示器上的1px
  • 0.5在正常显示

0.5不是像素坐标系中的物理度量(不存在半像素),因此渲染系统通常会在所有表示十进制的东西周围创建一个反混叠。

这种情况也会发生,你可能已经看到了不必要的模糊,当框架有小数点时,通常可以通过在UIView函数中传递框架来修复它。

要绘制一条像素线,我引用苹果对此的指示

在高分辨率显示器上(缩放因子为2.0),一条宽为一点的线根本不会被反别名,因为它占据两个完整的像素(从-0.5到+0.5)。若要绘制一条仅覆盖单个物理像素的线,则需要使其厚度为0.5点,并将其位置偏移0.25点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36423622

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档