Вопрос по iphone, objective-c, uikit, uiview, border – Core Graphics не рисует линию на правильной ширине

2

Я пытаюсь объединить границу на UIView с линией, нарисованной в drawRect. Я использую для обоих одинаковую ширину. Но проблема в том, что иногда полученная ширина нарисованных линий одинакова для обоих, а иногда нет - это даже зависит от ориентации устройства! Но даже без изменения ориентации устройства его ширина, в общем, все же не одинакова.

Граница рисуется с:

<code>view.layer.borderColor = [UIColor blackColor].CGColor;
view.layer.borderWidth = 1.0f;
</code>

Над этим представлением находится другое представление, которое является подклассом UIView. Оба вида имеют одинаковую ширину, и этот второй вид покрывает верхнюю часть представленного выше вида. Покрывающее представление использует следующий код в drawRect, чтобы нарисовать линию слева, которая должна идеально совпасть с границей вышеупомянутого представления ниже:

<code>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);
</code>

Есть идеи, как этого достичь? Прямо сейчас, даже если ширина всегда равна 1,0f, это просто совпадение, если обе линии нарисованы с одинаковой видимой шириной.

Цель состоит в том, чтобы получить нечто, похожее на вид с закругленными углами внизу, но обычными краями сверху. Вот почему я это делаю. Первый вид имеет закругленные углы, а второй вид сверху соответствует ширине, но покрывает верхнюю часть, поэтому закругленные углы сверху не видны.

Скриншот в портрете: enter image description here

Скриншот в пейзаже: enter image description here

Желтый вид выше белого. Черные линии белого вида отображаются в результате view.layer.borderWidth = 1.0f. Черные линии слева и справа от желтого вида рисуются в drawRect с кодом выше. Изменения ориентации вызывают перерисовку, но сам код чертежа остается прежним. Оба снимка экрана сделаны с iPhone с дисплеем Retina (iPhone 4S).

Насколько я могу судить, все значения являются "целыми числами":

<code>x: 0.000000, y: 0.000000
width: 264.000000, height: 10.000000
frame.origin.x: 33.000000, frame.origin.y: 38.000000
</code>
Можете ли вы предоставить скриншот? Mike Weller
Добавлены скриншоты :) aus

Ваш Ответ

1   ответ
8

что линия, которую вы рисуете, не выровнена по пикселям. Если я ошибаюсь, игнорируйте мой тангенс здесь. Но, тем не менее, это полезная информация.

Я собираюсь взять несколько скриншотов из этого видео WWDC 2011:

& quot; 1-29 Сессия 129 - Практическое рисование для разработчиков iOS & quot;

Я предлагаю вам посмотреть все это. Соответствующий раздел начинается около отметки 20:50.

По сути, представьте, что вы хотите нарисовать линию 1pt от (1,2) до (4,2)

enter image description here

Базовая графика будет пытаться центрировать ее по значению у, равному 2,0. Это означает, что он попытается нарисовать линию с верхним краем при y = 1.5 и нижним краем при y = 2.5:

enter image description here

На дисплее сетчатки это будет работать нормально, потому что y = 1.5 и y = 2.5 выровнены по пикселям:

enter image description here

Однако на экране без сетчатки графическая система будет вынуждена заполнить 2 вертикальных пикселя с половинной интенсивностью, чтобы получить наиболее близкое соответствие:

enter image description here

Обратите внимание, что этот эффект будетstill быть замеченным на дисплеях сетчатки, когда вы имеете дело с меньшими значениями дробных точек. Таким образом, эти проблемы все еще можно увидеть на дисплеях сетчатки в зависимости от кадра вашего вида.

Чтобы решить эту проблему, всякий раз, когда у вас есть нечетная ширина линии, вам нужно сместить значение точки, где вы ее рисуете, на 0,5 Вы должны сместить его вверх / вниз / влево / вправо в зависимости от ситуации.

enter image description here

Надеюсь, это поможет. Без скриншота трудно сказать, в чем ваша проблема.

Большое спасибо за информацию. Я тоже смотрел видео. Я добавил скриншоты в исходное сообщение. Похоже, что выравнивание может быть проблемой, но я использую только "целое число" значения и I 'm тестирование на дисплее сетчатки. Кроме того, почему это не влияет на нормальную границу? aus

Похожие вопросы