2016-06-14 155 views
3

我需要在UIView中生成一条曲线,如下图所示。我必须使用UIBezierPath。请帮助我解决这个问题。如何在UIView中绘制贝塞尔曲线

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

Example of bezier path

+0

请参考以下链接https://www.raywenderlich.com/34003/core-graphics-tutorial-curves-and-layers –

+0

我觉得这链接对你有用http://stackoverflow.com/questions/12904767/drawing-a-bezier-curve-between-a-set-of-given-points – Birendra

+0

是他们使用图像作为曲线的任何限制? @Diksha – Dalvik

回答

8

绘制了坚实的某个特定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该路径,然后添加作为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 

国债收益率:

enter image description here

或者,如果你想用的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; 
} 

从本质上讲,这是相同的thetaradius,但开始左下角,设置centersize.width/2.0, radius,并且电弧±theta

enter image description here

+0

感谢rob.you救了我再次..我想学习这个..实际上不知道如何处理UIBeizers,我想学习这个,所以你能帮我从哪里开始......谢谢... :) – Diksha

+0

@Elan - 有关贝塞尔路径的基础知识,请参阅Apple文档(https://developer.apple.com/library/ios/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/BezierPaths/BezierPaths.html#//apple_ref/doc/uid/TP40010156-CH11-SW1)或谷歌“uibezierpath教程”。为了达到理想的数学路径,这是从我的旧时高中三角学中吸取的。 :)底线,只需要开始在自定义的'UIView'子类(如上面)或'CAShapeLayer'中构建自己的'UIBezierPath',我相信你会很快把它捡起来。它看起来不那么难。 – Rob