8

I have a UIImageView. Inside that I am drawing a line wit user touch event. Problem is that a line can be drawn anywhere in UIImageview, but I like to draw line with image pattern only.

For example, look at this image. I need to draw line on image pattern only.

enter image description here

This is my code:

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{

    UITouch *touch = [[event allTouches] anyObject];
    touchPoint = [touch locationInView:self.imgColor];
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
    [path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];
    startingPoint=touchPoint;
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = [path CGPath];
    shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
    shapeLayer.lineWidth = 3.0;
    shapeLayer.fillColor = [[UIColor redColor] CGColor];
    [self.imgColor.layer addSublayer:shapeLayer];
    [arrLayer addObject:shapeLayer];
    NSLog(@"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y);



}

I hope some one solve my problem.

NightFury
  • 13,436
  • 6
  • 71
  • 120
Kishore Kumar
  • 4,265
  • 3
  • 26
  • 47

2 Answers2

8

You can try this way.

Let's say you have a bezierPath called maskPath,in my case it is textPath which is used to mask the imageView.

I am using a simple maskView which draws letter Q on imageView.

Adding the maskPath: (Adds a simple Q shaped mask to the imageView)

-(void)applyMask{

//// Text Drawing
textPath = [UIBezierPath bezierPath];
[textPath moveToPoint: CGPointMake(181, 179.8)];
[textPath addLineToPoint: CGPointMake(166, 197.2)];
[textPath addLineToPoint: CGPointMake(189.7, 216.1)];
[textPath addCurveToPoint: CGPointMake(160, 222.1) controlPoint1: CGPointMake(180.1, 220.1) controlPoint2: CGPointMake(170.2, 222.1)];
[textPath addCurveToPoint: CGPointMake(126.4, 214.45) controlPoint1: CGPointMake(147, 222.1) controlPoint2: CGPointMake(135.8, 219.55)];
[textPath addCurveToPoint: CGPointMake(103.3, 194.2) controlPoint1: CGPointMake(117, 209.35) controlPoint2: CGPointMake(109.3, 202.6)];
[textPath addCurveToPoint: CGPointMake(90.1, 165.85) controlPoint1: CGPointMake(97.3, 185.8) controlPoint2: CGPointMake(92.9, 176.35)];
[textPath addCurveToPoint: CGPointMake(85.9, 133.9) controlPoint1: CGPointMake(87.3, 155.35) controlPoint2: CGPointMake(85.9, 144.7)];
[textPath addCurveToPoint: CGPointMake(90.1, 101.95) controlPoint1: CGPointMake(85.9, 123.1) controlPoint2: CGPointMake(87.3, 112.45)];
[textPath addCurveToPoint: CGPointMake(103.3, 73.6) controlPoint1: CGPointMake(92.9, 91.45) controlPoint2: CGPointMake(97.3, 82)];
[textPath addCurveToPoint: CGPointMake(126.4, 53.35) controlPoint1: CGPointMake(109.3, 65.2) controlPoint2: CGPointMake(117, 58.45)];
[textPath addCurveToPoint: CGPointMake(160, 45.7) controlPoint1: CGPointMake(135.8, 48.25) controlPoint2: CGPointMake(147, 45.7)];
[textPath addCurveToPoint: CGPointMake(193.6, 53.35) controlPoint1: CGPointMake(173, 45.7) controlPoint2: CGPointMake(184.2, 48.25)];
[textPath addCurveToPoint: CGPointMake(216.7, 73.6) controlPoint1: CGPointMake(203, 58.45) controlPoint2: CGPointMake(210.7, 65.2)];
[textPath addCurveToPoint: CGPointMake(229.9, 101.95) controlPoint1: CGPointMake(222.7, 82) controlPoint2: CGPointMake(227.1, 91.45)];
[textPath addCurveToPoint: CGPointMake(234.1, 133.9) controlPoint1: CGPointMake(232.7, 112.45) controlPoint2: CGPointMake(234.1, 123.1)];
[textPath addCurveToPoint: CGPointMake(228.1, 171.85) controlPoint1: CGPointMake(234.1, 147.1) controlPoint2: CGPointMake(232.1, 159.75)];
[textPath addCurveToPoint: CGPointMake(209.5, 202.6) controlPoint1: CGPointMake(224.1, 183.95) controlPoint2: CGPointMake(217.9, 194.2)];
[textPath addLineToPoint: CGPointMake(181, 179.8)];
[textPath closePath];
[textPath moveToPoint: CGPointMake(244, 259.3)];
[textPath addLineToPoint: CGPointMake(258.4, 241.3)];
[textPath addLineToPoint: CGPointMake(230.2, 219.1)];
[textPath addCurveToPoint: CGPointMake(254.5, 180.7) controlPoint1: CGPointMake(241, 208.3) controlPoint2: CGPointMake(249.1, 195.5)];
[textPath addCurveToPoint: CGPointMake(262.6, 133.9) controlPoint1: CGPointMake(259.9, 165.9) controlPoint2: CGPointMake(262.6, 150.3)];
[textPath addCurveToPoint: CGPointMake(256.15, 91.75) controlPoint1: CGPointMake(262.6, 119.3) controlPoint2: CGPointMake(260.45, 105.25)];
[textPath addCurveToPoint: CGPointMake(236.8, 55.9) controlPoint1: CGPointMake(251.85, 78.25) controlPoint2: CGPointMake(245.4, 66.3)];
[textPath addCurveToPoint: CGPointMake(204.7, 31) controlPoint1: CGPointMake(228.2, 45.5) controlPoint2: CGPointMake(217.5, 37.2)];
[textPath addCurveToPoint: CGPointMake(160, 21.7) controlPoint1: CGPointMake(191.9, 24.8) controlPoint2: CGPointMake(177, 21.7)];
[textPath addCurveToPoint: CGPointMake(115.3, 31) controlPoint1: CGPointMake(143, 21.7) controlPoint2: CGPointMake(128.1, 24.8)];
[textPath addCurveToPoint: CGPointMake(83.2, 55.9) controlPoint1: CGPointMake(102.5, 37.2) controlPoint2: CGPointMake(91.8, 45.5)];
[textPath addCurveToPoint: CGPointMake(63.85, 91.75) controlPoint1: CGPointMake(74.6, 66.3) controlPoint2: CGPointMake(68.15, 78.25)];
[textPath addCurveToPoint: CGPointMake(57.4, 133.9) controlPoint1: CGPointMake(59.55, 105.25) controlPoint2: CGPointMake(57.4, 119.3)];
[textPath addCurveToPoint: CGPointMake(63.85, 176.05) controlPoint1: CGPointMake(57.4, 148.5) controlPoint2: CGPointMake(59.55, 162.55)];
[textPath addCurveToPoint: CGPointMake(83.2, 211.9) controlPoint1: CGPointMake(68.15, 189.55) controlPoint2: CGPointMake(74.6, 201.5)];
[textPath addCurveToPoint: CGPointMake(115.3, 236.65) controlPoint1: CGPointMake(91.8, 222.3) controlPoint2: CGPointMake(102.5, 230.55)];
[textPath addCurveToPoint: CGPointMake(160, 245.8) controlPoint1: CGPointMake(128.1, 242.75) controlPoint2: CGPointMake(143, 245.8)];
[textPath addCurveToPoint: CGPointMake(211.3, 233.2) controlPoint1: CGPointMake(179.8, 245.8) controlPoint2: CGPointMake(196.9, 241.6)];
[textPath addLineToPoint: CGPointMake(244, 259.3)];
[textPath closePath];
[UIColor.blackColor setFill];
[textPath fill];

maskLayer = [CAShapeLayer layer];
maskLayer.path = [textPath CGPath];
maskLayer.strokeColor = [[UIColor blackColor] CGColor];
maskLayer.lineWidth = 3.0;
maskLayer.fillColor = [[UIColor redColor] CGColor];
[self.imgView.layer addSublayer:maskLayer];

}

You already have the method:

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{

        UITouch *touch = [[event allTouches] anyObject];
        CGPoint touchPoint = [touch locationInView:self.imgView];

        if ([textPath containsPoint:touchPoint]) {
            path=nil; //this is not need,unless u want to start a new path everytime this condition executes.
            path = [UIBezierPath bezierPath];
            [path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
            [path addLineToPoint: CGPointMake(_startingPoint.x,_startingPoint.y)];
            _startingPoint=touchPoint;

        drawLayer = [CAShapeLayer layer];
        drawLayer.path = [path CGPath];
        drawLayer.strokeColor = [[UIColor blackColor] CGColor];
        drawLayer.lineWidth = 3.0;
        drawLayer.fillColor = [[UIColor redColor] CGColor];
        [self.imgView.layer addSublayer:drawLayer];
        NSLog(@"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y);

        }
}

You can now verify , if the touch point is in the textPath whcih is a bezierPath. If the touchPoint is in the textPath, then allow the draw, else dont draw.

The result will be something like this:

enter image description here

As you see, this code will allow you to draw only in the masked path. If you want to draw outside of the textPath, then you can do simply:

  if (![textPath containsPoint:touchPoint]) {
 path=nil; //this is not need,unless u want to start a new path everytime this condition executes.
 path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
[path addLineToPoint:CGPointMake(_startingPoint.x,_startingPoint.y)];
_startingPoint=touchPoint;

    drawLayer = [CAShapeLayer layer];
    drawLayer.path = [path CGPath];
    drawLayer.strokeColor = [[UIColor blackColor] CGColor];
    drawLayer.lineWidth = 3.0;
    drawLayer.fillColor = [[UIColor redColor] CGColor];
    [self.imgView.layer addSublayer:drawLayer];
    NSLog(@"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y);


}

Note: You need to take care of your touches moved method in drawing the line. As the bezier path method addLineToPoint will add line to the touchPoint and this line may cross the maskedPath. You need to make sure you are close the previosu bezier path and start a new one to avoid the lines to be drawn on the outside part of masked area.

Meet Doshi
  • 4,241
  • 10
  • 40
  • 81
Teja Nandamuri
  • 11,045
  • 6
  • 57
  • 109
  • but the image is not static here ,then how i have to calculate the uibezierPath . – Kishore Kumar Jan 11 '16 at 14:48
  • What Image ? In your case, are you talking about the I shaped mask ? – Teja Nandamuri Jan 11 '16 at 14:49
  • yes brother for me that image is not static ,then how i have to calculate the uibeizerPath path .... – Kishore Kumar Jan 11 '16 at 14:50
  • How are you drawing the I on imageview ? Is it an image or is it a mask ? – Teja Nandamuri Jan 11 '16 at 14:51
  • its a image only @mr.t – Kishore Kumar Jan 11 '16 at 14:52
  • IT would be very complex to detect the touch on certain color pattern on the image. You need to have a bezier path drawn as a mask to the imageView. Try creating the mask shape using bezier path.If you want the I shaped mask, I can draw it for u. – Teja Nandamuri Jan 11 '16 at 14:55
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/100390/discussion-between-kishore-kumar-and-mr-t). – Kishore Kumar Jan 11 '16 at 14:55
  • Yeah I did. Check ur spam or other folder . Or send a hi msg to my email tejanvm@gmail.com, I will reply back – Teja Nandamuri Jan 12 '16 at 12:15
  • may be it will helpfull for you http://stackoverflow.com/questions/34736949/how-to-find-out-uncoloured-area-uibeizerpath/34739531#34739531 ,but i didn't receive your mail ,i send invitation to you .please refer that answer and tell me what was going on that code only 50% i understood . – Kishore Kumar Jan 12 '16 at 13:00
0

I assume you are you trying to display alphabets in some language, may be you can use that language font for dynamic display. Just a thought. Together with the logic mentioned above you can try this.

Kannan Prasad
  • 1,796
  • 22
  • 27
  • that grey colour part is the uiimageview ,that white color part is the image ,is there any way to find out the uncolored cgrectpoints – Kishore Kumar Jan 12 '16 at 05:58