如何在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; } 

这只是使用一个小三angular来计算视angular的高度和宽度的弧的angular度和半径。

一旦你有了,你可以使用该path构build一个CAShapeLayer ,然后将其添加为一个UIView的子层,或者你可以实现自己的drawRect方法来调用fillpath。 (或者,你已经用core-graphics标记了这个标记,你也可以用CoreGraphics调用自定义drawRect ,但是我不确定为什么要这样做。)

例如,您可以定义一个使用CAShapeLayerCurvedView类:

 // 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 

如果您想让弧线占据视图的底部,则path将如下所示:

 - (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; } 

从本质上说,这是相同的thetaradius ,但从左下angular开始,将center设置为size.width / 2.0, radius和arc从M_PI_2 * 3.0 ± theta

在这里输入图像说明