在iOS6中控制MKMapView的动画速度

Fel*_*lix 8 iphone animation mkmapview ios ios6

我正试图在地图视图上关注汽车.

此代码应以相同的速度为汽车和地图设置动画,以便注释视图始终显示在中心:

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

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

[UIView commitAnimations];
Run Code Online (Sandbox Code Playgroud)

它在iOS 5中运行良好.在iOS 6中,地图不再是动画,但汽车确实有动画效果.

我试过[mapView setCenterCoordinate:co animated:YES],但后来我无法控制动画速度.它将始终使用默认持续时间(0.2秒)进行动画处理.

pol*_*987 11

我今天遇到了同样的问题.我认为这个问题并不依赖于MKMapView,而是(新)方式ios6管理动画.

似乎在ios6中,如果动画在前一个动画完成之前发生(取决于运行循环),则旧动画会被新动画中断.我认为只有在使用"beginFromCurrentState"选项或属性(取决于你是否使用基于块的动画)时才会出现这种情况(通过新的选项).

可以肯定的是,我认为您应该尝试使用基于块的动画来查看您的动画是否真的被另一个动画中断.

此代码必须与您的代码等效,并允许您查看动画是否已被中断或取消(如果"已完成"为假):

[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);
}];
Run Code Online (Sandbox Code Playgroud)

(在iOS <6中,"完成"应该是真的...)

在我的例子中,似乎我的动画被以下UIViewController的方法中断,这是由系统在动画块中执行的,中断了我的动画链:

- (void)viewWillAppear:(BOOL)animated;
- (void)viewDidAppear:(BOOL)animated;
Run Code Online (Sandbox Code Playgroud)


jbo*_*row 7

我发现如果格式如下,标准UIView AnimationWithDuration将适用:

// create a region with a center coordinate and a degree span
let center = CLLocationCoordinate2D(latitude: 42.3601, longitude: -71.0689)
let span = MKCoordinateSpanMake(1.0, 1.0)
let region = MKCoordinateRegion(center: center, span: span)

UIView.animateWithDuration(3.0,
             delay: 0.0,
           options: .CurveEaseInOut | .AllowUserInteraction,
        animations: {
                    self.mapView.setRegion(region, animated: true);
        },
        completion: { finished in
                    println("completed 3 second animation to new region")
        })
Run Code Online (Sandbox Code Playgroud)

希望对你有用!:)

(注意:有人向我指出,这个响应面向iOS7/8,问题出在iOS6上.)


而且,这个简单实际上可以正常工作......

    let c = mkMap.userLocation.coordinate
    let r = CLLocationDistance( 1500 )
    let cr = MKCoordinateRegionMakeWithDistance( c, r, r )

    UIView.animate(withDuration: 1.4, animations: { [weak self] in

        self?.mkMap.setRegion( cr, animated: true)
    })
Run Code Online (Sandbox Code Playgroud)


Fel*_*lix 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;
Run Code Online (Sandbox Code Playgroud)

但是我发现了一个具有持续时间参数的私有方法。所以我通过子类化 MKMapView 并覆盖私有方法(仅存在于 iOS6 中)解决了我的问题:

MyMapView.h

#import <MapKit/MapKit.h>

@interface MyMapView : MKMapView

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

@end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我添加了 2 个属性,允许您覆盖默认动画时间。overridesAnimationDuration要在区域更改之前将其设置为“是”,请设置mapAnimationDuration为所需的持续时间并切换overridesAnimationDuration在代表呼叫中切换为“否” mapView:regionWillChangeAnimated:

请注意,这可能在未来的 iOS 版本中不起作用,因为它是私有 API。Apple 可以删除或更改此方法。

  • @jfisk 我不知道,但是使用此代码的 3 个应用程序更新已获得批准,没有任何问题 (2认同)