问题
I am drawing annotations on a view. The line annotation is causing a problem;
I have a parent class of Shape (extended from UIView). All the annotations are subclass of shape. In each annotation class i have override the drawRect method. DrawingCanvas class (extended from UIView and is a subview of my viewController's parent view) handles the pan gesture. Here is a piece of code
-(void) panGestureRecognizer: (UIPanGestureRecognizer *) panGesture {
static CGPoint initialPoint;
CGPoint translation = [panGesture translationInView:panGesture.view];
static Shape *shape;
if(panGesture.state == UIGestureRecognizerStateBegan) {
initialPoint = [panGesture locationInView:panGesture.view];
if(selectedShape == nil) {
if([selectedOption isEqualToString:@"line"]) {
shape = [[Line alloc] initWithFrame:CGRectMake(initialPoint.x, initialPoint.y, 10, 10) isArrowLine:NO];
((Line *)shape).pointStart = [panGesture.view convertPoint:initialPoint toView:shape];
}
[panGesture.view addSubview:shape];
}
[shape setNeedsDisplay];
}
else if(panGesture.state == UIGestureRecognizerStateChanged) {
if([shape isKindOfClass:[Line class]]) {
CGRect newRect = shape.frame;
if (translation.x < 0) {
newRect.origin.x = initialPoint.x + translation.x - LINE_RECT_OFFSET;
newRect.size.width = fabsf(translation.x) + LINE_RECT_OFFSET * 2;
}
else {
newRect.size.width = translation.x + LINE_RECT_OFFSET * 2;
}
if (translation.y < 0) {
newRect.origin.y = initialPoint.y + translation.y - LINE_RECT_OFFSET;
newRect.size.height = fabsf(translation.y) + LINE_RECT_OFFSET * 2;
}
else {
newRect.size.height = translation.y + LINE_RECT_OFFSET * 2;
}
shape.frame = newRect;
CGPoint endPoint = CGPointMake(initialPoint.x + translation.x, initialPoint.y + translation.y);
((Line *)shape).pointStart = [panGesture.view convertPoint:initialPoint toView:shape];
((Line *)shape).pointEnd = [panGesture.view convertPoint:endPoint toView:shape];
[shape setNeedsDisplay];
}
}
}
Line drawRect contains
-(void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);
CGContextSetStrokeColorWithColor(context, self.color.CGColor);
CGContextSetFillColorWithColor(context, self.color.CGColor);
CGContextMoveToPoint(context, pointStart.x, pointStart.y);
CGContextAddLineToPoint(context, pointEnd.x, pointEnd.y);
CGContextSetLineWidth(context, 2.f);
CGContextStrokePath(context);
}
For moving and resizing i am handling touchEvents For moving the annotation i am doing this in touchesMoved
UITouch *touch = [[event allTouches] anyObject];
CGPoint newPoint = [touch locationInView:self];
CGPoint previousPoint = [touch previousLocationInView:self];
CGRect rect = self.frame;
rect.origin.x += newPoint.x - previousPoint.x;
rect.origin.y += newPoint.y - previousPoint.y;
self.frame = rect;
[self setNeedsDisplay];
It's all good till here, but now for resizing the line by dragging the endpoints of it creates the confusion to me. I have placed to imageViews at the end point. On touches began i am detecting the end point like this
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self];
if(CGRectContainsPoint(imageView1.frame, touchPoint) || CGRectContainsPoint(imageView2.frame, touchPoint)) {
isEndPoint = YES;
}
if isEndPoint is YES then i have to resize the line. I need to know on which direction am i dragging. how to update the points (i have taken to class variables of CGPoint; pointStart, pointEnd) and the frame.
Kindly suggest the resizing trick to update the points and the frame.
回答1:
For determining the line's direction:
You can do the following:
Line starting from Start Point:
a) Greater 'X' than the Start Point's X
Line is approaching towards right side
b) Less 'X' than the Start Point's X
line is approaching to the left side.
c) Greater Y'' than the Start point's 'Y'
Line is going downwards.
d) Less 'Y' than the Start point's 'Y'
Line is going Upwards.
Line starting from End Point:
a) Greater 'X' than the End Point's X
Line is approaching towards right side
b) Less 'X' than the End Point's X
line is approaching to the left side.
c) Greater Y'' than the End point's 'Y'
Line is going downwards.
d) Less 'Y' than the End point's 'Y'
Line is going Upwards.
If the line is being drawn from the End point then keep the Start Point unchanged, else if the line is starting from Start Point, keep the Start Point unchanged.
After drawing the line, you just need to update the Rect of the Line.
For that you need to add 2 more CGPoint
properties to the Line's Class.
1. Initial point, 2. Last Point.
Initially set the initial point equivalent to the Start Point and initially set the Last Point equivalent to the End Point.
Afterwards on every piece of line added to the Current Line
, just update these 2 properties with proper comparison to the Start and End Points. I am giving you a hint of proper comparisons:
For example:
Compare all the 4 points that is Initial Point
, Last Point
, Start Point
and End Point
.
Updating Initial Point and Last Point:
Set the Initial Point's
'X' and 'Y' equivalent to the Minimum 'X' and Minimum 'Y' among all these 4 points.
Set the Last Point's
'X' and 'Y' equivalent to the Maximum 'X' and Maximum 'Y' among these 4 points.
Make the Line's Rect according to these 2 points Initial Point
and Last Point
.
I hope this solves your problem.
来源:https://stackoverflow.com/questions/18229683/resize-line-from-endpoints