尝试在MapView中模拟路线

我有一个从文件中parsing的CLLocation对象数组。 我想模拟用户正在沿着这条路线移动,我已经实现了这一点:

 for (CLLocation *loc in simulatedLocs) { [self moveUser:loc]; sleep(1); } 

这是在循环中调用的方法:

 - (void)moveUser:(CLLocation*)newLoc { CLLocationCoordinate2D coords; coords.latitude = newLoc.coordinate.latitude; coords.longitude = newLoc.coordinate.longitude; CustomAnnotation *annotation = [[CustomAnnotation alloc] initWithCoordinate:coords]; annotation.title = @"User"; // To remove the previous location icon NSArray *existingpoints = self.mapView.annotations; if ([existingpoints count] > 0) { for (CustomAnnotation *annotation in existingpoints) { if ([annotation.title isEqualToString:@"User"]) { [self.mapView removeAnnotation:annotation]; break; } } } MKCoordinateRegion region = { coords, {0.1, 0.1} }; [self.mapView setRegion:region animated:NO]; [self.mapView addAnnotation: annotation]; [self.mapView setCenterCoordinate:newLoc.coordinate animated:NO]; } 

但是在运行iPhone模拟器时,只有数组及其区域中的最后一个位置才会显示在mapView中。 我想模拟用户每1秒“移动”,我怎么能这样做?

谢谢!

一次循环遍历所有位置并在每次迭代中都进入sleep将不起作用,因为UI将被阻塞,直到循环结束。

相反,安排moveUser方法为每个位置单独调用,以便在整个序列中不阻止用户界面。 调度可以使用NSTimer或可能更简单,更灵活的方式完成,如performSelector:withObject:afterDelay:方法。

保持一个索引伊娃尔,以跟踪移动到哪个位置moveUser被调用。

例如:

 //instead of the loop, initialize and begin the first move... slIndex = 0; //this is an int ivar indicating which location to move to next [self manageUserMove]; //a helper method -(void)manageUserMove { CLLocation *newLoc = [simulatedLocs objectAtIndex:slIndex]; [self moveUser:newLoc]; if (slIndex < (simulatedLocs.count-1)) { slIndex++; [self performSelector:@selector(manageUserMove) withObject:nil afterDelay:1.0]; } } 

现有的moveUser:方法不需要改变。

请注意,用户体验和代码可以简化,如果不是每次再次删除和添加注释,而是在开始时添加一次注释,而只是在每次“移动”时更改它的coordinate属性。

你不应该使用MKAnnotation,但MKPolyline。 检查文档 。 另外,请查看2010年的WWDC MapKitvideo。它有一个可变MKPolyline的例子。

你的问题是for循环与睡眠,阻塞主线程,直到循环结束。 这将冻结整个用户界面,包括您在moveUser中所做的任何更改。

而不是for循环,使用NSTimer,每秒触发一次,每做一步。

或者,为了获得更平滑的效果,请设置一个animation,沿着预定义的path移动注释的位置。