UIView roundedCorners и UIBezierPath bezierPathWithRoundedRect дают несколько разные результаты.

Я пытался воссоздать поведение UIView cornerRadius с помощью UIBezierPath. Я знал о методе bezierPathWithRoundedRect, и мне он показался самым чистым способом добиться того же результата.

Однако после сравнения результатов обоих методов между ними есть небольшая визуальная разница, и я не понимаю, почему.

Вот фрагменты кода и изображения: UIView + angleRadius + backgroundColor:

UIView *foo = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
foo.backgroundColor = UIColor.blueColor;
foo.layer.cornerRadius = 50;
[self.view addSubview foo];

угловой радиус

CALayer + bezierPathWithRoundedRect + addSublayer:

UIView *foo = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
CAShapeLayer *bar = [CAShapeLayer layer];
bar.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 100, 100) 
                                      cornerRadius:50].CGPath;
bar.fillColor = UIColor.blueColor.CGColor;
[foo.layer addSublayer:bar];
[self.view addSubview:foo];

подслой

CALayer + bezierPathWithRoundedRect + маска:

UIView *foo = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
CAShapeLayer *bar = [CAShapeLayer layer];
bar.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 100, 100) 
                                      cornerRadius:50].CGPath;
bar.fillColor = UIColor.clearColor.CGColor;
foo.backgroundColor = UIColor.blueColor;
foo.layer.mask = bar;
[self.view addSubview:foo];

маска

Хотя оба метода bezierPath (добавить как подслой или маскирование) создавали одно и то же изображение, оба они отличались от метода UIView + angleRadius.

Вот визуальная разница: введите здесь описание изображения

Что я пробовал:

  • Я попытался использовать параметр shouldRasterize, но это вызвало гораздо большую разницу и большее размытие.
  • Я попытался вычислить CGPath вручную, используя правильные углы с помощью CGPathAddArcToPoint, но это дало тот же результат, что и использование bezierPathWithRoundedRect.
  • Я попытался использовать fillRule как kCAFillRuleEvenOdd.
  • Я попытался установить для параметра AllowEdgeAntialiasing значение YES.
  • Я попытался создать круг, используя UIBezierPath.init(roundedRect: CGRect, byRoundingCorners: UIRectCorner, angleRadii: CGSize) и UIBezierPath.init(arcCenter:radius:startAngle:endAngle:по часовой стрелке:), но все равно тот же визуальный результат, что и у bezierPathWithRoundedRect

Любая помощь будет принята с благодарностью!

Для создания этих изображений я использовал Xcode 11.5 с iPhone SE (2-го поколения) на симуляторе iOS 13.5.


person Yarneo    schedule 20.07.2020    source источник


Ответы (1)


Вы заглядывали в allowsEdgeAntialiasing?

https://developer.apple.com/documentation/quartzcore/calayer/1621285-allowsedgeantialiasing?language=objc

person Cody Weaver    schedule 20.07.2020
comment
К сожалению, после установки свойства изображение визуально не меняется :( Спасибо, что поделились! - person Yarneo; 20.07.2020