2016-06-14 360 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