代码之家  ›  专栏  ›  技术社区  ›  Fattie

实际上复制/提取了苹果的“iPhoneX的连续角落”?

  •  13
  • Fattie  · 技术社区  · 6 年前

    iPhoneX与众不同的底角是苹果的新款(2017年) “iPhoneX的连续转角”

    对于任何有经验的iOS程序员来说 近似 曲线,但:

    有没有人像苹果一样知道如何实现这些目标?

    即使是私人电话,知道也很好。

    苹果没有解释这一点,这看起来确实很奇怪。

    enter image description here

    请注意,“近似”曲线很简单:

    要重复,

    1. 对于任何有经验的iOS程序员来说 近似 曲线。

    2. 这里要问的问题是,苹果究竟如何做到这一点?

    请不要发布更多的答案,告诉初学者如何绘制曲线和近似iPhone曲线。

    2 回复  |  直到 4 年前
        1
  •  3
  •   netdigger    5 年前

    从iOS 13开始,有一个API可用于此:

    https://developer.apple.com/documentation/quartzcore/calayercornercurve

    看见 CALayerCornerCurve.continuous

        2
  •  2
  •   clemens    6 年前

    我写了一个实验班,它构建了一条与 CALayer 由于 @Aflah Bhari氏 评论。层已设置其私有属性 continuousCorners 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 通过实验。如有必要,可以修改此值。我为半径选择的值不是最佳值,当然可以改进。但由于这取决于与篮筐的确切距离,我没有投入太多时间。