На самом деле дублировать/извлекать Apple "непрерывные углы для iPhoneX"?

Необычные нижние углы iPhoneX - это новые (2017) Apple, "сплошные углы для iPhoneX".

Для любого опытного программиста iOS это просто аппроксимировать кривую, но:

Кто-нибудь знает точно, как этого добиться, точно так же, как Apple?

Даже если это частный звонок, было бы хорошо узнать.

Кажется странным, что Apple не объяснила это.

enter image description here

Обратите внимание, что тривиально "приблизить" кривую:

Повторить,

  1. для любого опытного программиста iOS это просто аппроксимировать кривую.

  2. Вопрос, который здесь задают, заключается в том, как конкретно Apple сделать это?

Пожалуйста, не публикуйте больше ответов, показывающих новичкам, как нарисовать кривую и приблизить кривую iPhone.

Ответы

Ответ 1

Я написал экспериментальный класс, который строит путь CALayer который перекрывает границу CALayer из-за комментариев @Aflah Bhari. Слой установил для своего частного свойства continuousCorners YES значение YES. Это результат:

Layer and Path

Граница слоя голубая, а цвет пути - красный.

Вот код. Вы можете установить radius и insets в инспекторе атрибутов Interface Builder. Я создал изображение выше, установив класс представления контроллеров в ArcView, его радиус до 30.0 и вставки в (20.0, 20.0).

Вот код:

ArcView.h

IB_DESIGNABLE
@interface ArcView : UIView

@property(nonatomic) IBInspectable CGFloat radius;
@property(nonatomic) IBInspectable CGSize insets;

@end

ArcView.m

#import "ArcView.h"

@interface CALayer(Private)

@property BOOL continuousCorners;

@end

@interface ArcView()

@property (strong) CALayer *borderLayer;

@end


@implementation ArcView

- (void)setRadius:(CGFloat)inRadius {
    if(_radius != inRadius) {
        _radius = inRadius;
        self.borderLayer.cornerRadius = inRadius;
        [self setNeedsDisplay];
    }
}

- (void)setInsets:(CGSize)inInsets {
    if(!CGSizeEqualToSize(_insets, inInsets)) {
        _insets = inInsets;
        [self setNeedsLayout];
        [self setNeedsDisplay];
    }
}

- (void)awakeFromNib {
    [super awakeFromNib];
    self.borderLayer = [CALayer new];
    self.borderLayer.borderColor = [[UIColor blueColor] CGColor];
    self.borderLayer.borderWidth = 0.5;
    self.borderLayer.continuousCorners = YES;
    self.borderLayer.cornerRadius = self.radius;
    [self.layer addSublayer:self.borderLayer];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.borderLayer.frame = CGRectInset(self.bounds, self.insets.width, self.insets.height);
}

- (void)drawRect:(CGRect)rect {
    CGFloat theRadius = self.radius;
    CGFloat theOffset = 1.2 * theRadius;
    CGRect theRect = CGRectInset(self.bounds, self.insets.width, self.insets.height);
    UIBezierPath *thePath = [UIBezierPath new];
    CGPoint thePoint;

    [thePath moveToPoint:CGPointMake(CGRectGetMinX(theRect) + theOffset, CGRectGetMinY(theRect))];
    [thePath addLineToPoint:CGPointMake(CGRectGetMaxX(theRect) - theOffset, CGRectGetMinY(theRect))];
    thePoint = CGPointMake(CGRectGetMaxX(theRect), CGRectGetMinY(theRect));
    [thePath addQuadCurveToPoint:CGPointMake(CGRectGetMaxX(theRect), CGRectGetMinY(theRect) + theOffset) controlPoint:thePoint];
    [thePath addLineToPoint:CGPointMake(CGRectGetMaxX(theRect), CGRectGetMaxY(theRect) - theOffset)];
    thePoint = CGPointMake(CGRectGetMaxX(theRect), CGRectGetMaxY(theRect));
    [thePath addQuadCurveToPoint:CGPointMake(CGRectGetMaxX(theRect) - theOffset, CGRectGetMaxY(theRect)) controlPoint:thePoint];
    [thePath addLineToPoint:CGPointMake(CGRectGetMinX(theRect) + theOffset, CGRectGetMaxY(theRect))];
    thePoint = CGPointMake(CGRectGetMinX(theRect), CGRectGetMaxY(theRect));
    [thePath addQuadCurveToPoint:CGPointMake(CGRectGetMinX(theRect), CGRectGetMaxY(theRect) - theOffset) controlPoint:thePoint];
    [thePath addLineToPoint:CGPointMake(CGRectGetMinX(theRect), CGRectGetMinY(theRect) + theOffset)];
    thePoint = CGPointMake(CGRectGetMinX(theRect), CGRectGetMinY(theRect));
    [thePath addQuadCurveToPoint:CGPointMake(CGRectGetMinX(theRect) + theOffset, CGRectGetMinY(theRect)) controlPoint:thePoint];
    thePath.lineWidth = 0.5;
    [[UIColor redColor] set];
    [thePath stroke];
}

@end

Надеюсь, это поможет вам решить вашу проблему. Я нашел множитель 1.2 для экспериментов по theOffset. Вы можете изменить это значение, если это необходимо. Значение, которое я выбрал для радиуса, не является оптимальным и, безусловно, может быть улучшено. Но поскольку это зависит от точного расстояния от обода, я не вкладывал в это много времени.