KRDrawLine 2.0

KRDrawLine 2.0

gurongkang维护。



  • gurongkang

KRDrawLineView

swift版本见 KRDrawLineViewSwift

https://github.com/gurongkang/KRDrawLineViewSwift/tree/master

使用

1.引入方式

(1)CocoaPods

pod KRDrawLine

(2)手动添加

组成员中添加DrawLineView文件夹

2.初始化相关属性

@property (nonatomic, strong) KRDrawLineView *dashDrawLineView;


- (KRDrawLineView *)dashDrawLineView {
    if (_dashDrawLineView == nil) {
        _dashDrawLineView = [[KRDrawLineView alloc]init];
        //线宽度,pixel单位
        _dashDrawLineView.lineWidth = 1;
        //线样式
        _dashDrawLineView.lineStyle = KRDrawLineViewStyleDashLine;
        //线颜色
        _dashDrawLineView.lineColor = [UIColor redColor];
        //起点内边距
        _dashDrawLineView.paddingStart = 10;
        //结束点内边距
        _dashDrawLineView.paddingEnd = 40;
    }
    return _dashDrawLineView;
}

3.调整frame, 当frame 的高大于宽时认为是绘制竖线,否则认为是横线

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    self.dashDrawLineView.frame = CGRectMake(0, 164, self.view.bounds.size.width, 20);
  }

点与像素

iOS中使用的坐标系统都是由Point来描述的。

1个point不等于1 pixel,这样做的好处是屏蔽屏幕的差异,在布局时无需关注是否为Retina屏、x2、x3等屏幕信息。

点与像素的关系

在非Retina中:
1 point = 1 pixel

在iPhone 6、7、8中:
1 point = 2 pixel

在 iPhone Plus、iPhone X 中:
1 point = 3 pixel

具体通过[UIScreen mainScreen].scale获取缩放比例。pixel = scale * point

画一像素线

从上述关系中我们知道,直接使用point绘制一像素的线是不可行的。因此,自然而然地想通过 1/[UIScreen mainScreen].scale 来绘制一像素的线。但在实际使用过程中发现,画出的线有些并不是一像素线,具体原因请见 。 https://developer.apple.com/library/content/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html

在iOS绘图系统中使用antialiasing(反锯齿)技术。显示屏由许多小单元格组成,可以理解为一个单元格就代表了一个像素。

如果一条线正好落在一列或一行单元内,将渲染出标准的一像素线。

但如果线落在两行或两列中间时,就会变成非一像素线。此时系统会进行优化,使线条填充两个单元格,如图所示

整数点定义的位置位于像素之间的中点。例如,如果您从(1.0,1.0)到(1.0,10.0)绘制一条宽度为一像素的垂直线,您会得到一条模糊的灰色线。如果您绘制宽度为二像素的线,您会得到一条实心的黑色线,因为它完全覆盖了两个像素(指定点的两侧各一个)。通常,宽度为奇数物理像素的线条看起来比宽度以偶数物理像素衡量的线条更柔和,除非您调整它们的位位置使其完全覆盖像素。

解决方法:

在低分辨率显示器(缩放因子为1.0)上,一像素宽的线宽度为一像素。为了避免绘制宽度为一像素的水平和垂直线时出现反锯齿,如果线的宽度是奇数像素,您必须将位置偏移到整数位置两边0.5像素。如果线的宽度是偶数像素,为了避免出现模糊的线条,您不应进行偏移。在高分辨率显示器(缩放因子为2.0)上,一像素宽的线完全没有反锯齿,因为它占据了两个完整的像素(从-0.5到+0.5)。要绘制仅覆盖单个物理像素的线条,您需要将其宽度设置为0.5像素,并将其位置偏移0.25像素。

在非高清屏上,一个Point对应一个像素。为了防止“antialiasing”导致的奇数像素的线渲染时出现失真,您需要设置偏移0.5 Point。

在高清屏幕上,要绘制一像素的线,需要设置线宽为0.5个Point,并设置为偏移0.25 Point。

如果线宽为偶数Point,则不要设置偏移,否则线条也会失真。

解决

实际开发者经常会遇到开发一像素线的情况,为此创建了KRDrawLineView

在KRDrawLineView中定义了两个宏

#define SINGLE_LINE_WIDTH (1 / [UIScreen mainScreen].scale)
#define SINGLE_LINE_ADJUST_OFFSET ((1 / [UIScreen mainScreen].scale) / 2)

在绘制线条时,对奇数宽度进行处理

if (((int)(width * [UIScreen mainScreen].scale) + 1) % 2 == 0) {
            adjustPixelOffset = SINGLE_LINE_ADJUST_OFFSET;
   }

参考

http://www.cnblogs.com/smileEvday/p/iOS_PixelVsPoint.html