Skip to content

Instantly share code, notes, and snippets.

@maddiesch
Created December 3, 2013 21:50
Show Gist options
  • Save maddiesch/7778066 to your computer and use it in GitHub Desktop.
Save maddiesch/7778066 to your computer and use it in GitHub Desktop.
Simple drawing view based on UIPanGestureRecognizer.
#import <UIKit/UIKit.h>
@interface DrawView : UIView
@property (nonatomic) CGMutablePathRef drawingPath;
@property (nonatomic) CGPoint lastPoint;
@end
#import "DrawView.h"
CGRect DrawViewCGRectFromPointsMinimumSize(CGPoint p1, CGPoint p2, CGSize size) {
return CGRectMake(MIN(p1.x, p2.x), MIN(p1.y, p2.y), MAX(fabs(p1.x - p2.x), size.width), MAX(fabs(p1.y - p2.y), size.height));
}
void GetArrayPoints_CGPathApplierFunc(void *info, const CGPathElement *element) {
NSMutableArray *array = (__bridge NSMutableArray *)info;
if (element->type == kCGPathElementMoveToPoint || element->type == kCGPathElementAddLineToPoint) {
CGPoint point = element->points[0];
[array addObject:[NSValue valueWithCGPoint:point]];
}
}
#define DrawLineWidth 4.0
@implementation DrawView
#pragma mark -
#pragma mark - Life cycle
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
UIPanGestureRecognizer *panner = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureDidPan:)];
[self addGestureRecognizer:panner];
}
return self;
}
- (void)dealloc {
if (_drawingPath != NULL) {
CGPathRelease(_drawingPath);
_drawingPath = NULL;
}
}
#pragma mark -
#pragma mark - Draw
- (void)drawRect:(CGRect)rect {
if (_drawingPath != NULL) {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
CGContextSetLineWidth(ctx, DrawLineWidth);
CGContextSetLineCap(ctx, kCGLineCapRound);
CGContextSetLineJoin(ctx, kCGLineJoinRound);
CGContextSetMiterLimit(ctx, 2.0);
CGContextSetStrokeColorWithColor(ctx, [[UIColor orangeColor] CGColor]);
CGContextAddPath(ctx, _drawingPath);
CGContextDrawPath(ctx, kCGPathStroke);
CGContextRestoreGState(ctx);
}
}
#pragma mark -
#pragma mark - Gesture
- (void)panGestureDidPan:(UIPanGestureRecognizer *)panner {
// Start
if (panner.state == UIGestureRecognizerStateBegan) {
// Reset the path
if (_drawingPath != NULL) {
CGPathRelease(_drawingPath);
_drawingPath = NULL;
}
_lastPoint = CGPointZero;
// Create a new path
_drawingPath = CGPathCreateMutable();
// Start the new path
CGPoint point = [panner locationInView:self];
CGPathMoveToPoint(_drawingPath, nil, point.x, point.y);
// Change
} else if (panner.state == UIGestureRecognizerStateChanged) {
if (_drawingPath != NULL) {
// Add to the path
CGPoint point = [panner locationInView:self];
CGPathAddLineToPoint(_drawingPath, nil, point.x, point.y);
// Draw the line
if (CGPointEqualToPoint(_lastPoint, CGPointZero)) {
// If there a last point then we'll redraw everything
[self setNeedsDisplay];
} else {
// Only redraw what has changed.
CGRect render = DrawViewCGRectFromPointsMinimumSize(_lastPoint, point, CGSizeMake(DrawLineWidth, DrawLineWidth));
[self setNeedsDisplayInRect:UIEdgeInsetsInsetRect(render, UIEdgeInsetsMake(-DrawLineWidth, -DrawLineWidth, -DrawLineWidth, -DrawLineWidth))];
}
_lastPoint = point;
}
// Ended
} else if (panner.state == UIGestureRecognizerStateEnded) {
NSMutableArray *array = [NSMutableArray array];
CGPathApply(_drawingPath, (__bridge void *)(array), &GetArrayPoints_CGPathApplierFunc);
NSLog(@"%@",array);
// Reset the path
if (_drawingPath != NULL) {
CGPathRelease(_drawingPath);
_drawingPath = NULL;
}
_lastPoint = CGPointZero;
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment