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

sleepループが終了するメソッドまでUIがブロックされるため、各反復で一度にすべての場所をループすることはできません。

代わりにmoveUser、シーケンス全体でUIがブロックされないように、場所ごとに個別に呼び出されるようにメソッドをスケジュールします。NSTimerスケジューリングは、メソッドなど、またはおそらくより単純でより柔軟なものを使用して実行できますperformSelector:withObject:afterDelay:

moveUserインデックスivarを保持して、呼び出されるたびに移動する場所を追跡します。

例えば:

//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:方法を変更する必要はありません。


注釈を毎回削除して追加する代わりに、最初に1回追加し、coordinate「移動」ごとにプロパティを変更するだけで、ユーザーエクスペリエンスとコードを簡略化できることに注意してください。

于 2012-10-16T17:07:09.167 に答える
0

MKAnnotationではなく、MKPolylineを使用する必要があります。ドキュメントを確認してください。また、2010年のWWDCMapKitビデオを確認してください。可変MKPolylineの例があります。

于 2012-10-16T15:51:54.263 に答える
0

問題は、スリープを含むforループが、forループの終わりまでメインスレッドをブロックしていることです。これにより、moveUserで行った変更を含め、その期間全体でユーザーインターフェイス全体がフリーズします。

forループの代わりに、毎秒起動し、毎回1ステップ実行するNSTimerを使用します。

または、よりスムーズな効果を得るには、事前定義されたパスに沿って注釈の位置を移動するアニメーションを設定します。

于 2012-10-16T17:07:21.720 に答える