2

我正在尝试将 UIView 上的边框与 drawRect 中绘制的线条结合起来。我使用两个相同的宽度。但问题是,有时绘制的线的宽度对两者来说是相同的,有时是不同的——这甚至会随着设备方向的变化而变化!但即使不改变设备方向,它的宽度通常仍然不一样。

边框是用以下方式绘制的:

view.layer.borderColor = [UIColor blackColor].CGColor;
view.layer.borderWidth = 1.0f;

在该视图之上是另一个视图,它是 UIView 的子类。两个视图具有相同的宽度,第二个视图覆盖了上面视图的顶部。覆盖视图使用 drawRect 中的以下代码在左侧绘制一条线,该线应该与其下方的上述视图的边框完美对齐:

CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat x = self.bounds.origin.x;
CGFloat y = self.bounds.origin.y;
CGFloat width = self.bounds.size.width;
CGFloat height = self.bounds.size.height;

CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
CGContextSetLineWidth(context, 1.0f);

// Left line
CGContextMoveToPoint(context, x, y);
CGContextAddLineToPoint(context, x, height);
CGContextStrokePath(context);

// Right line
CGContextMoveToPoint(context, width - 1.0f, y);
CGContextAddLineToPoint(context, width - 1.0f, height);
CGContextStrokePath(context);

有什么想法可以实现吗?现在,即使宽度始终为 1.0f,如果两条线都以相同的可见宽度绘制,这只是巧合。

目标是最终得到一个看起来像底部圆角但顶部通常边缘的视图。这就是我这样做的原因。第一个视图有圆角,上面的第二个视图在宽度上与之匹配,但覆盖了顶部,因此顶部的圆角不可见。

纵向截图: 在此处输入图像描述

横屏截图: 在此处输入图像描述

黄色视图位于白色视图之上。由于 view.layer.borderWidth = 1.0f 绘制了白色视图的黑线。黄色视图左右的黑线是用上面的代码在drawRect中绘制的。方向更改会触发重绘,但绘图代码本身保持不变。两张截图均来自配备 Retina 显示屏的 iPhone(iPhone 4S)。

据我所知,所有值都是“整数”:

x: 0.000000, y: 0.000000
width: 264.000000, height: 10.000000
frame.origin.x: 33.000000, frame.origin.y: 38.000000
4

1 回答 1

8

我猜你画的线不是像素对齐的。如果我错了,那么请忽略我的切线。但它仍然是有用的信息。

我将从这个 WWDC 2011 视频中借用一些截图:

《1-29 Session 129 - iOS 开发者实战图》

我建议你看整个事情。相关部分在 20:50 左右开始。

基本上,假设你想画一条从 (1,2) 到 (4,2) 的 1pt 线

在此处输入图像描述

核心图形将尝试将其沿 y 值(即 2.0)居中。这意味着它将尝试绘制顶部边缘在 y=1.5 且底部边缘在 y=2.5 的线:

在此处输入图像描述

在视网膜显示器上,这可以正常工作,因为 y=1.5 和 y=2.5 是像素对齐的:

在此处输入图像描述

然而,在非视网膜显示器上,图形系统将被迫以半强度填充 2 个垂直像素,以获得最接近的匹配:

在此处输入图像描述

请注意,当您处理较小的小数点值时,仍会在视网膜显示器上看到此效果。所以这个问题仍然可以在视网膜显示器上看到,具体取决于您的视图框架。

为了解决这个问题,任何时候你有一个奇数的线宽,你需要将你绘制它的点值偏移 0.5。您需要根据情况向上/向下/向左/向右偏移它。

在此处输入图像描述

我希望这有帮助。没有截图很难说你的问题是什么。

于 2012-04-04T10:12:34.493 回答