IOS line measurement in the picture

I need help to start drawing lines with a circle at the ends and measure its length. I can draw a line, but I canโ€™t get it moving by spending hours publishing on SO.

So, please see the image below and let me know to get started. Any sample or tutorial using goal c will help.

enter image description here

Thanks:)

+5
source share
1 answer

This idea looked like a fun implementation, so I launched a new project in Xcode and created a conceptual confirmation.

LineView (subclass of UIView)

This class is responsible for drawing two circles and a line connecting their centers.

class LineView: UIView { var startPoint: CGPoint? var endPoint: CGPoint? override init(frame: CGRect) { super.init(frame: frame) self.setup() } required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.setup() } private func setup() { self.backgroundColor = UIColor.clearColor() self.multipleTouchEnabled = true } override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { self.updatePointsWithTouches(touches) } override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { self.updatePointsWithTouches(touches) } override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { self.clearPoints() } override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) { self.clearPoints() } private func updatePointsWithTouches(touches: Set<UITouch>) { if touches.count >= 1 { self.startPoint = touches[advance(touches.startIndex, 0)].locationInView(self) } if touches.count >= 2 { self.endPoint = touches[advance(touches.startIndex, 1)].locationInView(self) } self.setNeedsDisplay() } private func clearPoints() { self.startPoint = nil self.endPoint = nil self.setNeedsDisplay() } // MARK: - Drawing override func drawRect(rect: CGRect) { // draw circle at startPoint if let sp = self.startPoint { self.drawTouchCircleAtPoint(sp) } // draw circle at endPoint if let ep = self.endPoint { self.drawTouchCircleAtPoint(ep) } // draw line between points if let sp = self.startPoint, ep = self.endPoint { self.drawLineBetweenFirstPoint(sp, secondPoint: ep) } } private func drawTouchCircleAtPoint(p: CGPoint) { let context = UIGraphicsGetCurrentContext() CGContextSaveGState(context) CGContextSetLineWidth(context, 2.0) CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.6) CGContextAddArc(context, px, py, CGFloat(30.0), CGFloat(0.0), CGFloat(M_PI * 2), 1) CGContextFillPath(context) CGContextRestoreGState(context) } private func drawLineBetweenFirstPoint(p1: CGPoint, secondPoint p2: CGPoint) { let context = UIGraphicsGetCurrentContext() CGContextSaveGState(context) CGContextSetStrokeColorWithColor(context, UIColor.whiteColor().colorWithAlphaComponent(0.6).CGColor) CGContextSetLineWidth(context, 1.0) CGContextMoveToPoint(context, p1.x, p1.y) CGContextAddLineToPoint(context, p2.x, p2.y) CGContextStrokePath(context) CGContextRestoreGState(context) } } 

This class represents two private properties: startPoint and endPoint , which track where the user's fingers touch the view.

In this class, you will find the setup() function, which is called from all initializers. Here self.multipleTouchEnabled = true is crucial, so the view can detect multiple touches at the same time.

The touchesBegan/Moved/Ended/Cancelled functions call helper functions that retrieve the locations of the UITouch instances in the touches set.

Finally, the last three functions are responsible for drawing circles and a connecting line.

InteractiveImageView (subclass of UIImageView)

 class InteractiveImageView: UIImageView { private var lineView: LineView! required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.setup() } override init(frame: CGRect) { super.init(frame: frame) self.setup() } private func setup() { self.userInteractionEnabled = true self.lineView = LineView(frame: self.bounds) self.addSubview(self.lineView) } } 

This subclass of UIImageView has a built-in LineView for capturing multitouch events.


You can also use these storyboard classes! Just drag and drop the UIImageView , change its class to InteractiveImageView , set the correct limits and run the application. I will leave it up to you to draw the text on the axis between the center of the circles.

Here is a picture of my confirmation concept.


For those looking for an Objective-C solution, see the LineView and InteractiveImageView implementation files below.

LineView (in Objective-C)

 #import "LineView.h" @interface LineView () @property (nonatomic) CGPoint startPoint; @property (nonatomic) CGPoint endPoint; @end @implementation LineView - (instancetype)init { self = [super init]; if (self) { [self setup]; } return self; } - (instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { [self setup]; } return self; } - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self setup]; } return self; } - (void)setup { self.backgroundColor = [UIColor clearColor]; self.multipleTouchEnabled = true; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self updatePointsWithTouches:touches]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { [self updatePointsWithTouches:touches]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [self clearPoints]; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [self clearPoints]; } - (void)clearPoints { self.startPoint = CGPointZero; self.endPoint = CGPointZero; [self setNeedsDisplay]; } - (void)updatePointsWithTouches:(NSSet *)touches { if (touches.count >= 1) { UITouch *touch = [touches allObjects][0]; self.startPoint = [touch locationInView:self]; } if (touches.count >= 2) { UITouch *touch = [touches allObjects][1]; self.endPoint = [touch locationInView:self]; } [self setNeedsDisplay]; } - (void)drawRect:(CGRect)rect { if (self.startPoint.x != 0 && self.startPoint.y != 0) { [self drawTouchCircleAtPoint:self.startPoint]; } if (self.endPoint.x != 0 && self.endPoint.y != 0) { [self drawTouchCircleAtPoint:self.endPoint]; } if (self.endPoint.x != 0 && self.endPoint.y != 0 && self.startPoint.x != 0 && self.startPoint.y != 0) { [self drawLineBetweenFirstPoint:self.startPoint end:self.endPoint]; } } - (void)drawLineBetweenFirstPoint:(CGPoint)startPoint end:(CGPoint)endPoint { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); CGContextSetStrokeColorWithColor(context, [[[UIColor whiteColor] colorWithAlphaComponent:0.6] CGColor]); CGContextSetLineWidth(context, 1.0); CGContextMoveToPoint(context, startPoint.x, startPoint.y); CGContextAddLineToPoint(context, endPoint.x, endPoint.y); CGContextStrokePath(context); CGContextRestoreGState(context); } - (void)drawTouchCircleAtPoint:(CGPoint)CirclePoint { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); CGContextSetLineWidth(context, 2.0); CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.6); CGContextAddArc(context, CirclePoint.x, CirclePoint.y, 30.0, 30.0, M_PI * 2, YES); CGContextFillPath(context); CGContextRestoreGState(context); } @end 

InteractiveImageView (in Objective-C)

 #import "InteractiveImageView.h" #import "LineView.h" @interface InteractiveImageView () @property (strong, nonatomic) LineView *lineView; @end @implementation InteractiveImageView - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self setup]; } return self; } - (instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { [self setup]; } return self; } - (void)setup { self.userInteractionEnabled = YES; self.lineView = [[LineView alloc] initWithFrame:self.bounds]; [self addSubview:self.lineView]; } @end 
+10
source

All Articles