如何使用UIBezierPath获取自定义形状并将其设置为子视图

时间:2015-05-20 16:17:32

标签: ios objective-c uiview touch uibezierpath

我正在使用UIBezierPath画一个矩形。以下代码在我的视图控制器中创建rect:

@interface ViewController ()
{
    TargetAreaView *targetView;  //TargetAreaView is a subclass of UIView
    UIView *detectionView;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    CGRect frame = self.view.frame;
    frame.size.height = frame.size.height - 200;
    detectionView = [[UIView alloc]initWithFrame:frame];
    targetView = [[TargetAreaView alloc]initWithFrame:detectionView.frame];
    targetView.backgroundColor = [UIColor clearColor];
    [self.view addSubview:targetView];

    // Do any additional setup after loading the view, typically from a nib.
}

我使用bezier路径在TargetAreaView类中绘制rect。 我在UIView子类中使用了以下代码:(TargetAreaView)

@interface TargetAreaView : UIView
{
    NSMutableArray *points;
    CGRect superViewFrame;
    CGPoint selectedPoint;
}

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self)
    {
        superViewFrame = frame;
        points = [[NSMutableArray alloc]init];

        CGPoint startPoint = CGPointMake(superViewFrame.size.width / 2 - 200/2, superViewFrame.size.height / 2 - 200/2);
        CGPoint heightPoint1 = CGPointMake(startPoint.x, startPoint.y + 200);
        CGPoint widthPoint1 = CGPointMake(startPoint.x + 200, startPoint.y + 200);
        CGPoint heightPoint2 = CGPointMake(startPoint.x + 200, startPoint.y);
        CGPoint widthPoint2 = CGPointMake(startPoint.x, startPoint.y);

        [points addObject:[NSValue valueWithCGPoint:startPoint]];
        [points addObject:[NSValue valueWithCGPoint:heightPoint1]];
        [points addObject:[NSValue valueWithCGPoint:widthPoint1]];
        [points addObject:[NSValue valueWithCGPoint:heightPoint2]];
        [points addObject:[NSValue valueWithCGPoint:widthPoint2]];
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    if (points && points.count > 0)
    {
        [self drawTargetArea:points];
        [self setNeedsDisplay];
    }
}

-(void)drawTargetArea:(NSMutableArray *)savedPoints
{

    UIBezierPath *aPath = [UIBezierPath bezierPath];
    // Set the starting point of the shape.
    for (int idx = 0; idx < savedPoints.count; idx++)
    {
        if (idx == 0)
        {
            NSValue *startPoint = [savedPoints objectAtIndex:idx];
            [aPath moveToPoint:startPoint.CGPointValue]; // Starting Point
        }
        else
        {
            NSValue *drawPoints = [savedPoints objectAtIndex:idx];
            [aPath addLineToPoint:drawPoints.CGPointValue]; // Add lines from previous to current point
        }
    }
    [aPath closePath]; // close the final path

    aPath.lineWidth = 10.0f;
    [[UIColor redColor] setStroke];
    [aPath stroke];
}

以上UIView子类代码生成rect,如下所示:

enter image description here

我写了逻辑来移动rect的角来改变它的形状,如下所示:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint startTouchPoint  = [touch locationInView:self]; //get the user touch position and check it is nearer in 10px range to any of the position in rect
    for (NSValue *aPoint in points)
    {
        CGPoint currentPoint = aPoint.CGPointValue;
        CGFloat distance = [self touchPositionDifference:startTouchPoint WithCornerPosition:currentPoint]; // Calculate the distance between user touch position and rect points
        if (distance < 10)
        {
            selectedPoint = currentPoint; // get the nearest point in a global variable
            break;
        }
    }
}

-(CGFloat)touchPositionDifference:(CGPoint)touchPosition WithCornerPosition:(CGPoint)cornnerPosition
{
    CGFloat dx= touchPosition.x - cornnerPosition.x;
    CGFloat dy= touchPosition.y - cornnerPosition.y;
    CGFloat distance= sqrt(dx*dx + dy*dy);

    return distance; // calculate and return distance between two points
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint touchEndPoint  = [touch locationInView:self];
     for (int idx = 0; idx < points.count; idx++)
    {
        NSValue *aPoint = [points objectAtIndex:idx];
        CGPoint currentPoint = aPoint.CGPointValue;
        if (CGPointEqualToPoint(currentPoint, selectedPoint)) 
        {
            [points replaceObjectAtIndex:idx withObject:[NSValue valueWithCGPoint:touchEndPoint]]; // get the global point value and touch ended value and replace the new value with old value
        }
    }
    [self setNeedsDisplay];// and draw the shape with new points
}

我能够得到如下的输出

enter image description here

我有返回代码以获取bezier路径,如下所示:

-(UIBezierPath *)getPath
{
    if (points.count <= 0) return nil;
    NSArray *oldPoints = points;

    UIBezierPath *aPath = [UIBezierPath bezierPath];

    // Set the starting point of the shape.
    CGPoint p1 = [[oldPoints objectAtIndex:0] CGPointValue];
    [aPath moveToPoint:CGPointMake(p1.x, p1.y)];

    for (uint i=1; i<oldPoints.count; i++)
    {
        CGPoint p = [[oldPoints objectAtIndex:i] CGPointValue];
        [aPath addLineToPoint:CGPointMake(p.x, p.y)];
    }
    [aPath closePath];
    return aPath; //This returns me a bezier path of the already drawn shape
}

我正在获取整个视图(在该视图中我有不规则形状View以绿色表示,形状以红色边框颜色表示),如下所示

enter image description here

我想单独获得特定形状(不规则形状)如下所示

我怎样才能做到这一点?我是否遵循正确的道路?

enter image description here

1 个答案:

答案 0 :(得分:0)

您可以使用以下代码绘制上述形状。

- (void)drawCanvas1WithFrame: (CGRect)frame
 {
//// Color Declarations
UIColor* color = [UIColor colorWithRed: 1 green: 0 blue: 0 alpha: 1];

//// Bezier Drawing
UIBezierPath* bezierPath = UIBezierPath.bezierPath;
[bezierPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 77.5, CGRectGetMinY(frame) + 39.5)];
[bezierPath addCurveToPoint: CGPointMake(CGRectGetMinX(frame) + 130.5, CGRectGetMinY(frame) + 14.5) controlPoint1: CGPointMake(CGRectGetMinX(frame) + 130.5, CGRectGetMinY(frame) + 14.5) controlPoint2: CGPointMake(CGRectGetMinX(frame) + 130.5, CGRectGetMinY(frame) + 14.5)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 122.5, CGRectGetMinY(frame) + 75.5)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 61.5, CGRectGetMinY(frame) + 110.5)];
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 77.5, CGRectGetMinY(frame) + 39.5)];
[UIColor.greenColor setFill];
[bezierPath fill];
[color setStroke];
bezierPath.lineWidth = 1;
[bezierPath stroke];
}