尝试在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移动注释的位置。