5

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 秒“移动”一次,我该怎么做?

谢谢!

4

3 回答 3

2

在每次迭代中使用 a 一次循环遍历所有位置是sleep行不通的,因为 UI 将被阻塞,直到循环所在的方法完成。

相反,安排moveUser为每个位置单独调用该方法,以便 UI 在整个序列中不会被阻塞。调度可以使用NSTimer或可能更简单和更灵活的方法来完成,例如performSelector:withObject:afterDelay:方法。

保留索引 ivar 以跟踪每次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请注意,如果不是每次都重新删除和添加注释,而是在开始时添加一次并在每次“移动”时 更改其属性,则可以简化用户体验和代码。

于 2012-10-16T17:07:09.167 回答
0

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

代替 for 循环,使用每秒触发一次并且每次执行一个步骤的 NSTimer。

或者,为了获得更平滑的效果,可以设置一个动画,沿着预定义的路径移动注释的位置。

于 2012-10-16T17:07:21.720 回答
0

您不应该使用 MKAnnotation,而是使用 MKPolyline。检查文档。另外,请查看 2010 年的 WWDC MapKit 视频。它有一个可变 MKPolyline 的示例。

于 2012-10-16T15:51:54.263 回答