如何在UIView中绘制贝塞尔曲线

迪克莎

我需要UIView绘制一条曲线,如下图所示。我要用UIBezierPath请帮我解决这个问题。

我还想知道如何从水平轴翻转曲线,这样我的弧线在顶部,底部在底部。

贝塞尔曲线路径的示例

要在特定的内绘制实心圆弧CGSize,可以这样定义UIBezierPath

- (UIBezierPath * _Nullable)pathOfArcWithinSize:(CGSize)size {
    if (size.width == 0 || size.height <= 0) return nil;

    CGFloat theta = M_PI - atan2(size.width / 2.0, size.height) * 2.0;
    CGFloat radius = self.bounds.size.height / (1.0 - cos(theta));

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0, 0)];
    [path addArcWithCenter:CGPointMake(size.width / 2.0, -radius + size.height) radius:radius startAngle:M_PI_2 + theta endAngle:M_PI_2 - theta clockwise:false];
    [path closePath];

    return path;
}

在给定视图的高度和宽度的情况下,这只是使用一些三角函数来计算圆弧的角度和半径。

有了该CAShapeLayer路径后,您可以使用该路径构造一个,然后将该路径添加为a的子层,UIView也可以实现自己的在该路径drawRect上调用方法fill(或者,考虑到您已经用标记了它,也可以drawRect使用CoreGraphics调用进行自定义,但是我不确定为什么要这么做。)

例如,您可以定义一个CurvedView使用CAShapeLayer以下内容

//  CurvedView.h

#import <UIKit/UIKit.h>

IB_DESIGNABLE
@interface CurvedView : UIView

@property (nonatomic, strong) IBInspectable UIColor *fillColor;

@end

//  CurvedView.m

#import "CurvedView.h"

@interface CurvedView ()
@property (nonatomic, weak) CAShapeLayer *curvedLayer;
@end

@implementation CurvedView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self configureView];
    }
    return self;
}

- (instancetype _Nullable)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {
        [self configureView];
    }
    return self;
}

- (void)configureView {
    self.fillColor = [UIColor whiteColor];

    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.fillColor = self.fillColor.CGColor;
    layer.strokeColor = [UIColor clearColor].CGColor;
    layer.lineWidth = 0;
    [self.layer addSublayer:layer];
    self.curvedLayer = layer;
}

- (void)setFillColor:(UIColor *)fillColor {
    _fillColor = fillColor;

    self.curvedLayer.fillColor = fillColor.CGColor;
}

- (void)layoutSubviews {
    [super layoutSubviews];

    self.curvedLayer.path = [self pathOfArcWithinSize:self.bounds.size].CGPath;
}

- (UIBezierPath * _Nullable)pathOfArcWithinSize:(CGSize)size {
    if (size.width == 0 || size.height <= 0) return nil;

    CGFloat theta = M_PI - atan2(size.width / 2.0, size.height) * 2.0;
    CGFloat radius = self.bounds.size.height / (1.0 - cos(theta));

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0, 0)];
    [path addArcWithCenter:CGPointMake(size.width / 2.0, -radius + size.height) radius:radius startAngle:M_PI_2 + theta endAngle:M_PI_2 - theta clockwise:false];
    [path closePath];

    return path;
}

@end

产生:

在此处输入图片说明

或者,如果您更愿意使用该drawRect方法而不是使用CAShapeLayer

//  CurvedView.m

#import "CurvedView.h"

@implementation CurvedView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self configureView];
    }
    return self;
}

- (instancetype _Nullable)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {
        [self configureView];
    }
    return self;
}

- (void)configureView {
    self.fillColor = [UIColor whiteColor];
}

- (void)setFillColor:(UIColor *)fillColor {
    _fillColor = fillColor;

    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect {
    UIBezierPath *path = [self pathOfArcWithinSize:self.bounds.size];
    [self.fillColor setFill];
    [path fill];
}

- (UIBezierPath * _Nullable)pathOfArcWithinSize:(CGSize)size {
    if (size.width == 0 || size.height <= 0) return nil;

    CGFloat theta = M_PI - atan2(size.width / 2.0, size.height) * 2.0;
    CGFloat radius = self.bounds.size.height / (1.0 - cos(theta));

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0, 0)];
    [path addArcWithCenter:CGPointMake(size.width / 2.0, -radius + size.height) radius:radius startAngle:M_PI_2 + theta endAngle:M_PI_2 - theta clockwise:false];
    [path closePath];

    return path;
}

@end

如果希望弧形占据视图的底部,则路径应如下所示:

- (UIBezierPath * _Nullable)pathOfArcWithinSize:(CGSize)size {
    if (size.width == 0 || size.height <= 0) return nil;

    CGFloat theta = M_PI - atan2(size.width / 2.0, size.height) * 2.0;
    CGFloat radius = self.bounds.size.height / (1.0 - cos(theta));

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0, size.height)];
    [path addArcWithCenter:CGPointMake(size.width / 2.0, radius) radius:radius startAngle:M_PI_2 * 3.0 + theta endAngle:M_PI_2 * 3.0 - theta clockwise:false];
    [path closePath];

    return path;
}

本质上,这与theta相同radius,但从左下角开始,将设置centersize.width / 2.0, radius,并从M_PI_2 * 3.0±弧起theta

在此处输入图片说明

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Android中绘制贝塞尔曲线

来自分类Dev

如何在贝塞尔曲线中添加渐变?

来自分类Dev

在UIView的贝塞尔曲线路径中绘制/绘制类似草图颜色的颜色

来自分类Dev

如何绘制贝塞尔曲线 C#

来自分类Dev

通过示例了解如何绘制 SVG 贝塞尔曲线

来自分类Dev

在QML中绘制点划线的贝塞尔曲线

来自分类Dev

如何在Flutter CustomPainter中使用贝塞尔曲线绘制形状

来自分类Dev

如何在圆形贝塞尔曲线路径内绘制图像

来自分类Dev

绘制SVG贝塞尔曲线

来自分类Dev

绘制贝塞尔曲线的半圆弧

来自分类Dev

使用Firemonkey绘制贝塞尔曲线

来自分类Dev

用Java绘制贝塞尔曲线

来自分类Dev

贝塞尔曲线绘制非常滞后

来自分类Dev

使用CubicTo绘制贝塞尔曲线

来自分类Dev

绘制贝塞尔曲线的半圆弧

来自分类Dev

贝塞尔曲线绘制非常滞后

来自分类Dev

在UIView中的贝塞尔曲线路径内像素描颜色一样绘制/绘画

来自分类Dev

如何使贝塞尔曲线中的线接点平滑?

来自分类Dev

如何在QML中渲染三次贝塞尔曲线?

来自分类Dev

如何在KineticJS中补间Shape或Group alogn贝塞尔曲线?

来自分类Dev

如何在paper.js中沿贝塞尔曲线弯曲的路径设置对象的动画?

来自分类Dev

如何在paper.js中沿贝塞尔曲线弯曲的路径设置对象的动画?

来自分类Dev

如何生成“厚”贝塞尔曲线?

来自分类Dev

如何使精灵遵循贝塞尔曲线

来自分类Dev

如何从图像模拟贝塞尔曲线?

来自分类Dev

CSS中的贝塞尔曲线?

来自分类Dev

CSS中的贝塞尔曲线?

来自分类Dev

如何在 HTML5 画布上使用二次贝塞尔曲线绘制小写 b

来自分类Dev

在html5画布中绘制动画的贝塞尔曲线时如何保持平滑的线条

Related 相关文章

热门标签

归档