-1

Is there any way to change the UIBezierPath drawing shape ,see the below image it like a line when user drag the finger,but i want star ,circle and other is there any way to achieve that.

enter image description here

My Expectation is enter image description here

This is my UIBezierPath code:

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        UITouch *touch = [[event allTouches] anyObject];
        touchPoint = [touch locationInView:self];

        if (!CGPointEqualToPoint(startingPoint, CGPointZero))
        {
            UIBezierPath *path = [UIBezierPath bezierPath];
            [path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
            [path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];

            CAShapeLayer *shapeLayer = [CAShapeLayer layer];
            shapeLayer.path = [path CGPath];
            shapeLayer.strokeColor = [single.arrColor[single.i] CGColor];
            if([UIDevice currentDevice].userInterfaceIdiom ==UIUserInterfaceIdiomPad)
            {
                shapeLayer.lineWidth = 7.0;

            }
            else
            {
                shapeLayer.lineWidth = 5.0;

            }
            shapeLayer.fillColor = [[UIColor redColor] CGColor];
            [self.layer addSublayer:shapeLayer];
            [clearBeizer addObject:shapeLayer];
        }
        startingPoint=touchPoint;
        //    [arrLayer addObject:shapeLayer];
        NSLog(@"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y);
    }
Kishore Kumar
  • 4,265
  • 3
  • 26
  • 47

3 Answers3

1

Yes, it is doable but it is not trivial. What you essentially want is to stroke a path with stars instead of normal dashes. As far as I know, iOS only provides an API for a standard methods, i.e. stroking with a rectangular dash pattern.

If you want to implement custom stroking, you have to do it yourself. You probably have to flatten the bezier path first. Then "walk" along the path and draw stars/circle/squirrels at certain interval manually. It is especially difficult if you need the interval between the stars to be equal.

You can have a look at DrawKit library for MacOS. DrawKit is for MacOS, not iOS! This is just a reference for you to get the idea.

DrawKit has NSBezierPath+Geometry.h category on NSBezierPath class. You can start with (NSBezierPath*)bezierPathWithZig:(CGFloat)zig zag:(CGFloat)zag method and see how zig-zagy path is implemented

https://github.com/DrawKit/DrawKit/.../NSBezierPath-Geometry.m#L1206

or wavy path [(NSBezierPath*)bezierPathWithWavelength:amplitude:spread:]

https://github.com/DrawKit/DrawKit/..../NSBezierPath-Geometry.m#L1270

Just FYI: UIBezierPath (iOS) often lacking methods that are available in NSBezierPath (MacOS)

If DrawKit confuses you, there are probably open-sourced drawing libraries for iOS on the Internet, try searching them and see how custom drawing is done.

euvs
  • 1,595
  • 13
  • 13
  • so there is no in build option @euvs correct , we need to made custom design for it. – Kishore Kumar Jan 27 '16 at 11:50
  • AFAIK you cant do it without Core-Graphics. The code in my question has almost everything you want. I did the same thing with that code. You just need a "Star" image. Pass it as a pattern (in callback), it will draw that image as a path for you. – Blind Ninja Jan 27 '16 at 11:55
  • @HarvantS. Will CGContextSetFillPattern function follow along a path and place stars at equal intervals _along_ the path? Or will it place stars in a grid-like pattern that are aligned on x,y axis and then use the path as a mask to show only some stars? – euvs Jan 27 '16 at 12:07
  • It will fill the pattern in bounding box (as same as simple color). It look like you are drawing with pencil or calk. http://thumbs.dreamstime.com/z/wax-crayon-hand-drawing-background-abstract-35695793.jpg something like this. If OP needs equal interval between two stars , he have to fine tune the algorithm. – Blind Ninja Jan 27 '16 at 13:40
1

Yes You can do that. But You have to get the custom shaped icons for this task.

You can try this excellent answer provided by RobMayoff here: and the git repo

Here is another way to do it:

I have made a simple Image Editing App similar to what your are doing .

enter image description here

You can draw the heart shapes on the image:

enter image description here

Like that, you can draw many custom shapes:

enter image description here

The code is pretty straight forward and simple:

You need to create few custom shaped erasers. I call them eraser becuase they just erase the pic :P .

Here are the methods for customising the eraser:

- (void)newMaskWithColor:(UIColor *)color eraseSpeed:(CGFloat)speed {
    wipingInProgress = NO;
    eraseSpeed = speed;  //how fast eraser should move
    maskColor = color; //eraser color
    [self setNeedsDisplay];
}
-(void)setErase:(UIImage *)img{
eraser =img; //set the custom shaped image here
} 

And to draw the custom shaped eraser on view:

   - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        wipingInProgress = YES;
    }
   - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
        if ([touches count] == 1) {
            UITouch *touch = [touches anyObject];
            location = [touch locationInView:self];
            location.x -= [eraser size].width/2;
            location.y -= [eraser size].width/2;
            [self setNeedsDisplay];
        }  
    }

and finally the draw rect method:

   - (void)drawRect:(CGRect)rect {

    CGContextRef context = UIGraphicsGetCurrentContext();
    if (wipingInProgress) {
        if (imageRef) {
            // Restore the screen that was previously saved
            CGContextTranslateCTM(context, 0, rect.size.height);
            CGContextScaleCTM(context, 1.0, -1.0);

            CGContextDrawImage(context, rect, imageRef);
            CGImageRelease(imageRef);

            CGContextTranslateCTM(context, 0, rect.size.height);
            CGContextScaleCTM(context, 1.0, -1.0);
        }

        [eraser drawAtPoint:location blendMode:kCGBlendModeDestinationOut alpha:eraseSpeed];
    }
    // Save the screen to restore next time around
    imageRef = CGBitmapContextCreateImage(context);

}

Here are some variables declared in the .h file:

CGPoint     location;
CGImageRef  imageRef;
UIImage     *eraser;
BOOL        wipingInProgress;
UIColor     *maskColor;
CGFloat     eraseSpeed;
Community
  • 1
  • 1
Teja Nandamuri
  • 11,045
  • 6
  • 57
  • 109
0

I am simply done this using UIImageView :

 UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:single.arrimages[single.colorimages]]];
                imageView.frame = CGRectMake(touchPoint.x, touchPoint.y, 30,30);
                [self addSubview:imageView];

just add image while user touch the screen.

get the x , y coordination of user touch and give it to uiimageview frame.

i Hope it will help for some one.

Kishore Kumar
  • 4,265
  • 3
  • 26
  • 47