8

地図ビューで車を追跡しようとしています。

このコードは、注釈ビューが常に中央に表示されるように、車と地図を同じ速度でアニメーション化する必要があります。

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDuration: 1.0];
[UIView setAnimationBeginsFromCurrentState:YES];

[car setCoordinate:coord];
[mapView setCenterCoordinate:coord];

[UIView commitAnimations];

iOS 5 では正常に動作しました。iOS 6 では、マップはアニメーション化されなくなりましたが、車はアニメーション化されます。

を試し[mapView setCenterCoordinate:co animated:YES]ましたが、アニメーションの速度を制御できません。常にデフォルトの長さ (0.2 秒) でアニメーション化されます。

4

3 に答える 3

11

今日、同じ種類の問題に遭遇しました。問題は MKMapView に依存しているのではなく、ios6 がアニメーションを管理する (新しい) 方法に依存していると思います。

iOS6 では、前のアニメーションが終了する前に (実行ループに応じて) アニメーションが発生すると、古いアニメーションが新しいアニメーションによって中断されるようです。これは、「beginsFromCurrentState」オプションまたはプロパティ(ブロックベースのアニメーションを使用しているかどうかに応じて)が(新しいものによって)使用されている場合にのみ発生すると思います。

確かに、ブロックベースのアニメーションを使用して、アニメーションが実際に別のアニメーションによって中断されているかどうかを確認する必要があると思います.

このコードはあなたのものと同等でなければならず、アニメーションが中断またはキャンセルされたかどうかを確認できます (「終了」が false の場合):

[UIView animateWithDuration:1.0 delay:0.0f options:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionBeginFromCurrentState) animations:^{

    [car setCoordinate:coord];
    [mapView setCenterCoordinate:coord];

} completion:^(BOOL finished){
    NSLog(@"has not been interrupted : %d", finished);
}];

(iOS < 6 では、"finished" が true のはずです...)

私の場合、アニメーション ブロック内のシステムによって実行された次の UIViewController のメソッドによってアニメーションが中断され、アニメーション チェーンが中断されたように見えました。

- (void)viewWillAppear:(BOOL)animated;
- (void)viewDidAppear:(BOOL)animated;
于 2012-10-16T14:19:40.500 に答える
4

でこれらのメソッドを使用すると、iOS 6 でアニメーションの速度を制御できないようですMKMapView

- (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;
- (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated;
- (void)setVisibleMapRect:(MKMapRect)mapRect animated:(BOOL)animate;
- (void)setVisibleMapRect:(MKMapRect)mapRect edgePadding:(UIEdgeInsets)insets animated:(BOOL)animate;

ただし、期間パラメーターを持つプライベート メソッドが見つかりました。そこで、MKMapView をサブクラス化し、private メソッド (iOS6 にのみ存在する) をオーバーライドすることで問題を解決しました。

MyMapView.h

#import <MapKit/MapKit.h>

@interface MyMapView : MKMapView

@property(nonatomic) BOOL overridesAnimationDuration;
@property(nonatomic) NSTimeInterval mapAnimationDuration;

@end

MyMapView.m

@interface MKMapView (Private)
- (void)_setZoomScale:(float)scale centerMapPoint:(CLLocationCoordinate2D)center duration:(double)d animationType:(int)animType;
@end

@implementation MyMapView
- (void)_setZoomScale:(float)scale centerMapPoint:(CLLocationCoordinate2D)center duration:(double)d animationType:(int)animType
{
    if (_overridesAnimationDuration) {
        d = _mapAnimationDuration;
    }
    [super _setZoomScale:scale centerMapPoint:center duration:d animationType:animType];
}    
@end

デフォルトのアニメーション時間をオーバーライドできる 2 つのプロパティを追加しました。overridesAnimationDuration地域を変更する前に YES に設定して使用するmapAnimationDurationには、目的の期間に設定しoverridesAnimationDuration、デリゲート コールで NO に切り替えますmapView:regionWillChangeAnimated:

これはプライベート API であるため、将来の iOS バージョンでは機能しない可能性があることに注意してください。Apple は、この方法を削除または変更できます。

于 2012-10-18T15:55:06.920 に答える