召集所有专家!我看到了各种帖子,老实说,我的需求与SO上的答案有些不同。
我想创建一个UI,让用户在特定区域(暂称为“画布”)上创建各种线条(直线、曲线、折线等)。每种线条可以有多个实例。然后用户可以根据需要拖动和编辑这些线条。因此,他们可以拉伸它,改变起点、终点等,甚至将整条线条拖到画布范围内。
我已经成功绘制了线条(使用
以下是我目前为止针对线类的代码(startHandle和endHandle是每端的手柄):
我想创建一个UI,让用户在特定区域(暂称为“画布”)上创建各种线条(直线、曲线、折线等)。每种线条可以有多个实例。然后用户可以根据需要拖动和编辑这些线条。因此,他们可以拉伸它,改变起点、终点等,甚至将整条线条拖到画布范围内。
我已经成功绘制了线条(使用
drawRect
),并在每条线的末端显示了可拖动的手柄(见参考图像)。用户可以拖动末端点以适应画布的范围。
我面临的问题是如何轻触来激活特定行的编辑。因此,默认情况下,拖动手柄不可见,用户可以轻触该行以激活“编辑”模式,并显示手柄(再次轻触取消选择)。因此,在上图中,我希望能够检测到黄色矩形区域的触摸。请记住,UIView边界是整个画布区域,以允许用户自由拖动,因此检测触摸显然很困难,因为还有透明区域,并且每行可能有多个实例。以下是我目前为止针对线类的代码(startHandle和endHandle是每端的手柄):
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint startPoint = CGPointMake(self.startHandle.frame.origin.x + self.startHandle.frame.size.width/2, self.startHandle.frame.origin.y + self.startHandle.frame.size.height/2);
CGPoint endPoint = CGPointMake(self.endHandle.frame.origin.x + self.endHandle.frame.size.width/2, self.endHandle.frame.origin.y + self.endHandle.frame.size.height/2);
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self];
if (CGRectContainsPoint(CGRectMake(startPoint.x, startPoint.y, endPoint.x - startPoint.x , endPoint.y - startPoint.y), touchLocation))
{
//this is the green rectangle! I want the yellow one :)
NSLog(@"TOUCHED IN HIT AREA");
}
}
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, self.bounds);
CGPoint startPoint = CGPointMake(self.startHandle.frame.origin.x + self.startHandle.frame.size.width/2, self.startHandle.frame.origin.y + self.startHandle.frame.size.height/2);
CGPoint endPoint = CGPointMake(self.endHandle.frame.origin.x + self.endHandle.frame.size.width/2, self.endHandle.frame.origin.y + self.endHandle.frame.size.height/2);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
CGContextSetLineWidth(context, 2.0f);
CGContextMoveToPoint(context, startPoint.x, startPoint.y ); //start at this point
CGContextAddLineToPoint(context, endPoint.x, endPoint.y); //draw to this point
self.arrow.angle = [self pointPairToBearingDegrees:startPoint secondPoint:endPoint];
self.arrow.center = endPoint;
[self.arrow setNeedsDisplay];
// and now draw the Path!
CGContextStrokePath(context);
}
我已经尝试过的事情:
- 尝试检测开始点和结束点之间绘制的矩形内的触摸,但是如果线的角度为45度(见绿色矩形),则返回的矩形不是我需要的。
- 在drawRect中尝试在顶部绘制另一条粗线,但是徒劳无功,因为我必须使它透明,并且它与视图的任何其他区域相同。还尝试检测颜色,但是同样这条粗线必须是透明的。
我真的很感谢在这方面提供任何帮助。如果您能向我展示如何对曲线进行此操作,则加分。非常感谢您阅读。
CGPath
时,我遇到了一些性能问题。每次用户移动端点或起点时,我需要重新绘制线条,而在这种情况下,CGPath的表现并不是很好,或者可能我没有用对它。再次感谢你!祝一切顺利。 - Gurtej SinghCGPath
和CGPathContainsPoint
是否有用。根据文档:“如果一个点在路径被填充时在绘制区域内,那么该点就包含在路径中。”因此,对于由路径“包围”的点,它基本上返回true。如果你只有一条线段,即使它是弯曲的,它也可能不会包围任何东西。 - Matthew Burke