4

I am working on digital signature on uiview. i create it normaly by this code, but i am not able to remove bezier path on button click.i am sharing my code PLease look at my code.

#import "Signature.h"

 @implementation Signature {
UIBezierPath *path;
UIImage *incrementalImage;
CGPoint pts[5]; // we now need to keep track of the four points of a Bezier segment and the first control point of the next segment
uint ctr;
  }

  - (id)initWithCoder:(NSCoder *)aDecoder
  {
if (self = [super initWithCoder:aDecoder])
{
    [self setMultipleTouchEnabled:NO];
    [self setBackgroundColor:[UIColor greenColor]];
    path = [UIBezierPath bezierPath];
    [path setLineWidth:2.0];
}
return self;

  }

   - (id)initWithFrame:(CGRect)frame
 {
self = [super initWithFrame:frame];
if (self) {
    [self setMultipleTouchEnabled:NO];
    path = [UIBezierPath bezierPath];
    [path setLineWidth:2.0];
}
return self;
   }

 - (void)drawRect:(CGRect)rect
    {
[incrementalImage drawInRect:rect];
[path stroke];
 }

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
  {
ctr = 0;
UITouch *touch = [touches anyObject];
pts[0] = [touch locationInView:self];
   }

    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
      {
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
ctr++;
pts[ctr] = p;
if (ctr == 4)
{
    pts[3] = CGPointMake((pts[2].x + pts[4].x)/2.0, (pts[2].y + pts[4].y)/2.0); // move the endpoint to the middle of the line joining the second control point of the first Bezier segment and the first control point of the second Bezier segment

    [path moveToPoint:pts[0]];
    [path addCurveToPoint:pts[3] controlPoint1:pts[1] controlPoint2:pts[2]]; // add a cubic Bezier from pt[0] to pt[3], with control points pt[1] and pt[2]

    [self setNeedsDisplay];
    // replace points and get ready to handle the next segment
    pts[0] = pts[3];
    pts[1] = pts[4];
    ctr = 1;
}
      }

   - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
   {
[self drawBitmap];
[self setNeedsDisplay];
[path removeAllPoints];
ctr = 0;
  }

  - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
 {
NSLog(@"hello");
[self touchesEnded:touches withEvent:event];
      }

    - (void)drawBitmap
      {
UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0.0);

if (!incrementalImage) // first time; paint background white
{
    UIBezierPath *rectpath = [UIBezierPath bezierPathWithRect:self.bounds];
    [[UIColor greenColor] setFill];
    [rectpath fill];
}
[incrementalImage drawAtPoint:CGPointZero];
[[UIColor blackColor] setStroke];
[path stroke];
incrementalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
    }

    - (void)erase {
NSLog(@"Erase Testing...");
 // self->path   = nil;  //Set current path nil
 //path   = [UIBezierPath bezierPath];
// [self setNeedsDisplay];
  }

I call erase method on unbutton click from another class, but I am not able to remove uibezeripath.

Pramod Karandikar
  • 5,289
  • 7
  • 43
  • 68
sandeep tomar
  • 303
  • 1
  • 5
  • 17
  • `incrementalImage` is resulting image? and you are setting on any imageview? – Ketan Parmar May 23 '16 at 11:02
  • no sir i just add a uiview and nothing else. i add uiview in the view controller and give a class signature – sandeep tomar May 23 '16 at 11:03
  • What is the exact problem? i am not getting what you need – Ketan Parmar May 23 '16 at 11:05
  • sir i am drawing signature by the above code, but when i want to erase that signature on button click, its not removing, here is my unbutton code from which i call erase method. - (IBAction)erase:(id)sender { NSLog(@"callPrint"); self->callerase = [[Signature alloc] init]; [self->callerase erase]; self.signature.backgroundColor = [UIColor redColor]; } – sandeep tomar May 23 '16 at 11:07
  • Are you erasing this from same class? or calling this method from other class? – Ketan Parmar May 23 '16 at 11:09
  • yes sir from where i create it , on the same class i call this method – sandeep tomar May 23 '16 at 11:10
  • this method called NSLog(@"Erase Testing..."); // self->path = nil; //Set current path nil //path = [UIBezierPath bezierPath]; // [self setNeedsDisplay]; } when press unbutton from view controller class – sandeep tomar May 23 '16 at 11:11
  • please give some idea sir – sandeep tomar May 23 '16 at 11:20

3 Answers3

2

Try using this to remove the UIBezierPath,

[path removeAllPoints];

If you use CAShapeLayer *rectLayer = [[CAShapeLayer alloc] init]; aswell then call this line too,

[rectLayer removeFromSuperlayer];
Maniganda saravanan
  • 2,188
  • 1
  • 19
  • 35
1

Check how i am using this in one of my project if it can help,

 - (void)drawRect:(CGRect)rect {

    [_path stroke];

 }


- (id)initWithFrame:(CGRect)frame{

self = [super initWithFrame: frame];

if (self) {
    // set Multiple touches Enabled to false for allow only single touch.
    [self setMultipleTouchEnabled: NO];
    _path = [UIBezierPath bezierPath];
    // set Line width.
    [_path setLineWidth:2.0];

 }
 return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

isMouseswipped = NO;  //for touches eneded to make dot
ctr = 0;
UITouch *myTouch = [touches anyObject];
pts[0] = [myTouch locationInView: self];


}

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

isMouseswipped = YES;   //for touches eneded to make dot
CustomSignatureViewController *csvc = [[CustomSignatureViewController alloc]init];

UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView: self];
ctr++;
pts[ctr] = p;

if (ctr == 4) {

    pts[3] = CGPointMake((pts[2].x + pts[4].x)/2.0, (pts[2].y + pts[4].y)/2.0);
    [_path moveToPoint: pts[0]];
    [_path addCurveToPoint: pts[3] controlPoint1:pts[1] controlPoint2:pts[2]];
    [self setNeedsDisplay];
    pts[0] = pts[3];
    pts[1] = pts[4];
    ctr = 1;

    csvc.status = 1;
    self.status = 1;
  }


}


- (void)erase {

_path   = nil;  

_path   = [UIBezierPath bezierPath]; 
[_path setLineWidth:2.0];
[self setNeedsDisplay];

}

This is custom class which returns uiview to fraw signature. It is subclass of UIView.

So when required signature, i import this class and instantiate it and got uiview object on which i can draw. then capture that view as image using graphics beginimage context!

Update :

In viewcontroller i am calling method like,

 -(void)clear : (id)sender{

  [signView erase];

  signView.status = 0;

 }

signView is signature class(as mentioned above)'s object. and erase is public method declared in .h file of signature class. (note : signature class is subclass of uiview so intance of it returns view onject so signView is uiview object)

Hope this will help :)

Ketan Parmar
  • 27,092
  • 9
  • 50
  • 75
  • sir i need to ask one question from where you call erase method? – sandeep tomar May 23 '16 at 11:37
  • i am calling erase method from another class which is my view controller. In this class i am making instance of this class which mentioned in answer and i have another method in viewcontroller class to capture image from this view after drawing signature – Ketan Parmar May 23 '16 at 11:42
  • i have two class one is signature and second is view controller. i add a uiview on view controller form storyboard give a class name signature. and add all the code in signature class – sandeep tomar May 23 '16 at 11:42
  • sir what is status here?, and ismouseswipped is a bool value i think? – sandeep tomar May 23 '16 at 11:46
  • check my update in answer. yes status is bool value, there is many other code because of other need in project – Ketan Parmar May 23 '16 at 11:49
  • where will i declare status??. in view controller class? – sandeep tomar May 23 '16 at 11:52
  • I think you not required status. I have used status only to check that is there any drawing? I am using that status in my capture click to check that user draw a signature or not – Ketan Parmar May 23 '16 at 11:54
  • sir one more question please. sign view is a uiview property outlet or class names. what will be sign view in my case. is it signature? – sandeep tomar May 23 '16 at 11:56
  • see, I have two class to manage signature. Let's say one as Signature and second is ViewController. Signature is subclass of `UIVIew` and ViewController is subclass of `UIVIewController`. my answer except update is Signature.m of mine. then i have import that class to viewcontroller and make object of it with custom init method which i have declared in answer. so that object is sign view. got it? – Ketan Parmar May 23 '16 at 12:00
  • just one question is left in my mind sir, where you get this signature in image form? – sandeep tomar May 23 '16 at 12:02
  • As you know you can draw on sign view as it is object of signature class. So signview is your view with drawing (signature), then i have one button called capture on it's click i am doing something like : UIGraphicsBeginImageContextWithOptions(signView.bounds.size, signView.opaque, 0.0); [signView.layer renderInContext: UIGraphicsGetCurrentContext()]; // UIImage *imgMySignature = UIGraphicsGetImageFromCurrentImageContext(); signView.img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); – Ketan Parmar May 23 '16 at 12:06
  • i will add this code in view controller class, right sir? – sandeep tomar May 23 '16 at 12:09
  • yes, i have button on view controller class and on it's action method i am getting image by adding this code! so i get signature as image then i can use it anywhere i need! – Ketan Parmar May 23 '16 at 12:11
  • this line will give me image of signature UIImage *imgMySignature = UIGraphicsGetImageFromCurrentImageContext(), sir what is img here? – sandeep tomar May 23 '16 at 12:14
  • It is simple image from `uiview`. In simple word converting uiview to image. If you want to send signature to server then how you send? so you can send this image to server. – Ketan Parmar May 23 '16 at 12:16
  • If you are asking about `signView.img` then img is uiimage property in signature class. so i am setting image there as per my need. – Ketan Parmar May 23 '16 at 12:17
  • ok sir thank you i got it, In my case i will get signature image from this line UIImage *imgMySignature = UIGraphicsGetImageFromCurrentImageContext(); and do something with image? – sandeep tomar May 23 '16 at 12:19
  • Yes, you can see i have one line commented. both line is same that giving image. i am storing it in singview.img, same you can use `UIImage *imgMySignature = UIGraphicsGetImageFromCurrentImageContext();` to get image from signature view – Ketan Parmar May 23 '16 at 12:21
  • Thanks you sir, i dont have word to say you thanks for you kind help – sandeep tomar May 23 '16 at 12:22
0

use this code it will help you

- (void)resetPath {
    path   = nil;  
    path   = [UIBezierPath bezierPath]; 
    [self setNeedsDisplay]; 
}

create this method in .h file of your subclass. From your UIViewController class you call this method whenever you need it

- (IBAction)youraction:(id)sender 
{
    [self.subclassedView resetPath];
}