撤消上次绘制的折线

时间:2014-12-17 03:17:36

标签: ios objective-c mkmapview mkoverlay mkpolyline

我一直致力于折线覆盖,当我被困住时得到了很好的帮助,我希望能再次提供一些帮助。

在我的项目中,我在地图上绘制折线,从触摸开始触及移动。我的手指被拖动的位置的坐标被添加到我的数组并显示。

当我想清除我的线条时,我只是清空阵列,这很好

但是,如果我想删除/撤消绘制的最后一行。我的印象是我可以减去阵列中的最后一个值,但在深入思考时我意识到我可能有问题。数组中的每个元素都是我的手指最后触摸的坐标。 我还没试过这个,但我想象的是如果我只减去数组的最后一个值,我将花费很长时间“擦除”我绘制的一条线。 我正在寻找一种方法,当我按下“撤消”时,它会删除我绘制的整条线。即使这条线从北美延伸到英格兰。

1 个答案:

答案 0 :(得分:0)

OP希望能够撤消绘制的最后一行。他想象的问题是从数组中删除单个元素在视觉上只会删除用户绘制的线条的一部分。 他希望做的是删除构成该行的数组中的所有元素。

我还没有完成绘图,但我的解决方案应该有效。

执行以下操作,创建一个枚举数据类型,该类型将为绘制到屏幕/添加到数组的每个坐标创建三种可能的状态。

此数据类型如下所示:

typedef NS_ENUM(NSInteger, PKLinePointState) {
    PKLinePointStart,
    PKLinePointMiddle,
    PKLinePointEnd
};

这里的想法是,您将使用此数据类型来确定数组中的哪些元素是起点,以及数组中的哪些元素是结束点。通过这种方式,您可以确定数组中的行,这样就可以确定要删除的元素数量,直到您点击状态为PKLinePointStart的坐标。

您不想只在数组中存储坐标,而是希望存储一个数据模型,该模型将包含更多信息,以便您可以完成您希望完成的性感事物。

第一个数据模型将用于存储数组中的起点和终点坐标和元素。这将使您更容易使用坐标。这就是它的样子:

<强> LinePointModel.h

typedef NS_ENUM(NSInteger, PKLinePointState) {
        PKLinePointStart,
        PKLinePointMiddle,
        PKLinePointEnd
    };

@interface LinePointModel : NSObject

@property (assign) CGPoint linePointCoordinate; 
@property (assign) PKLinePointState linePointState; 
@end

//you may want to create a custom initialiser so that the coordinate and state are initialised straight away.
//It would look something like this -(instanceType)initWithLinePointCoordinate:(CGPoint)coordinate andLinePointState:(PKLinePointState)linePointstate;

<强> LinePointModel.m

//I'll let you complete the initialiser method in the implementation file.

现在您已经创建了数据模型,可以在coordinates array中正确存储您的坐标,这里我将如何将它们添加到数组中。

逻辑阶段1:

当用户点击屏幕 - 调用touchesBegan方法时,您需要创建LinePointModel的实例并将其坐标值设置为用户点击的第一个坐标屏幕并将state设置为PKLinePointStart,这将标记该行的开头。将此元素添加到数组中。

然后,当用户拖动屏幕时,您将收到touchesMoved的多个坐标。在这里你将创建一个相同数据模型的实例再次设置坐标,但这次状态将存储为PKLinePointMiddle,我们真的不关心这些点,因为我们不会检查这个状态,但它仍然很好地赋予它一个值,以便我们知道数组中具有此状态的任何元素只有服务器形成一个点,最终形成整行的点。在这里,这些实例将一直多次添加到数组中,直到用户最终停止拖动 - 绘制当前行 - 在屏幕上。

touchesEnded方法被调用 - 表示行的结束 - 用户抬起他的手指时,这就是你创建数据模型的最后一个实例,相应地设置坐标的地方,以及最后状态将是PKLinePointEnd状态。同样,您也可以在数组中添加此实例。

现在你有了一个有意义的自定义数组,可以跟踪所有坐标但是可以让你知道哪个元素具有起始状态,中间和结束状态。

每个起始状态都与结束状态相结合,并且需要尽可能多的中间元素来构成该行。

如果您想在此处停止,只需运行for循环,并确定阵列中添加的最新startend元素。 :)

逻辑阶段2 - 改进算法:

现在你不想循环遍历数组中的数千个元素,只是为了确定你的数组中你需要返回多少只是为了删除一行,这将是低效的。这是第二个数据模型有用的地方。第二个数据模型将跟踪您的线条,并通过存储startend index来存储阵列中的哪些元素构成其线,甚至更好地存储坐标数组这就是我们要做的。

<强> LineArrayModel.h

@interface LineArrayModel : NSObject

@property (nonatomic, retain) NSMutableArray *arrayOfLinePoints;  //What matters.
//@property (assign) int lineNumber; 
//@property (assign) CGFloat lineThickness;
//@property (strong, nonatomic) UIColor *lineColor;
@end

使用此数据模型,您可以在用户在屏幕上绘制一条线时创建一个临时数组,并且一旦绘制完一条线,您将获取该数组并将其存储在{{ 1}};并且它将用于存储在名为myLinesArray的新数组中的此实例。这是您用于在屏幕上绘制线条的数组。

然后,只需撤消一行,您只需删除存储所有行的数组中LineArrayModel的最后一个实例,然后根据需要重新绘制行。

让我知道你是怎么过的。