MKMapView不会缩小

时间:2014-01-09 22:14:00

标签: google-maps mkmapview pinchzoom mkmapviewdelegate

我将地图围绕用户的位置居中,或者在缩放级别约为30英里的默认位置周围居中。问题是我可以放大但不能缩小。

每当我尝试缩小我的iPhone 5C时,当我移开手指捏时,地图会立即缩小。

我尝试添加mapView方法regionDidChangeAnimated和didChangeDragState以确定我正在重置视图的区域和中心,但这些似乎都没有改变缩小的能力。

无法弄清楚我在这里失踪了什么。谢谢你的帮助!

//
//  MapViewController.m


#import "MapViewController.h"
#import "MeetFetcher.h"
#import "MeetLocationAnnotation.h"
#import "MyAnnotations.h"


NSInteger const redPin = 0;
NSInteger const greenPin = 1;
NSInteger const purplePin = 2;

@interface MapViewController() <MKMapViewDelegate, CLLocationManagerDelegate>
@property (strong, nonatomic) IBOutlet MKMapView *mapView;

@end

@implementation MapViewController

@synthesize mapView = _mapView;
@synthesize annotations = _annotations;
@synthesize delegate = _delegate;
@synthesize beginningDateForSearch = _beginningDateForSearch;
@synthesize levelOfCompetition = _levelOfCompetition;
@synthesize meets = _meets;
@synthesize myLocationMngr = _myLocationMngr;


#pragma mark - Synchronize Model and View

- (NSArray *)mapAnnotations
{
    NSMutableArray *meetAnnotations = [NSMutableArray arrayWithCapacity:[self.meets count]];
    NSInteger iCount = 0;
    for (NSDictionary *meet in self.meets) {
        NSLog(@"In [%@ %@], iCount = %d and meet = %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), iCount, meet);
        [meetAnnotations addObject:[MeetLocationAnnotation annotationForMeet:meet]];
        iCount++;
        NSLog(@"\n \n meetAnnotations = %@",meetAnnotations);
    }
    return meetAnnotations;
}

- (void)updateMapView
{
    if (self.mapView.annotations) [self.mapView removeAnnotations:self.mapView.annotations];
    if (self.annotations) [self.mapView addAnnotations:self.annotations];
}

- (void)setMapView:(MKMapView *)mapView
{
    _mapView = mapView;
    [self updateMapView];
}

- (void)setAnnotations:(NSArray *)annotations
{
    _annotations = annotations;
    [self updateMapView];
}

- (void)setMeets:(NSArray *)meets
{
    if (_meets != meets) {
        _meets = meets;
    }
        // Model changed, so update our View in map
    NSLog(@"meets count in setMeets = %d", [meets count]);
    NSArray* listOfAnnotations = [self mapAnnotations];
    [self setAnnotations:listOfAnnotations];
    [self updateMapView];
}

#pragma mark - MKMapViewDelegate

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    MKPinAnnotationView *aView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"MapVC"];
    if (!aView) {
        aView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"MapVC"];
        aView.canShowCallout = YES;
        aView.rightCalloutAccessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
        aView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        aView.pinColor = myPinColor;

        // could put a rightCalloutAccessoryView here
    } else {

    aView.annotation = annotation;
    }


//    [(UIImageView *)aView.rightCalloutAccessoryView setImage:nil]; // Could replace rightCallOutButton with image.

    return aView;
}

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)aView
{
    UIImage *image = [self.delegate mapViewController:self imageForAnnotation:aView.annotation];
    [(UIImageView *)aView.leftCalloutAccessoryView setImage:image];
}

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    NSLog(@"callout accessory tapped for annotation %@", [view.annotation title]);
}

#pragma mark - View Controller Lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.mapView.delegate = self;

    self.myLocationMngr = [[CLLocationManager alloc] init];
    self.myLocationMngr.delegate = self;
    self.myLocationMngr.desiredAccuracy = 500; // 500 meters.

    if( [CLLocationManager locationServicesEnabled] ) {
        myPinColor = MKPinAnnotationColorGreen;
        [self.myLocationMngr startUpdatingLocation];
    } else {
        CLLocationCoordinate2D defaultCoordinateWhenCLLocationDisabled;
        defaultCoordinateWhenCLLocationDisabled.latitude = 45.194014;
        defaultCoordinateWhenCLLocationDisabled.longitude = -117.862015;

        MyAnnotations *annotation =
        [[MyAnnotations alloc] initWithCoordinates:defaultCoordinateWhenCLLocationDisabled
                                            title:DEFAULT_LOCATION_TITLE
                                         subTitle:DEFAULT_LOCATION_SUBTITLE
                                  selectedPinColor:redPin];
//        [self.mapView addAnnotation:annotation];

        [self mapView:self.mapView didAddAnnotationViews:(NSArray *)annotation];
    }

    //Set some paramater for the location object.
    [self.myLocationMngr setDistanceFilter:kCLDistanceFilterNone];
    [self.myLocationMngr setDesiredAccuracy:kCLLocationAccuracyBest];

    //Set the first launch instance variable to allow the map to zoom on the user location when first launched.
    firstLaunch=YES;

}

- (void)viewDidUnload
{
    [super viewDidUnload];
    [self setMapView:nil];
}

-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    CLLocation *lastLocation =[locations lastObject];

    CLLocationAccuracy accuracy = [lastLocation horizontalAccuracy];
    NSLog(@"Received location %@ with accuracy %f", lastLocation, accuracy);

    if(accuracy < 100.0)
    {
        MKCoordinateSpan span = MKCoordinateSpanMake(0.14, 0.14);
        region = MKCoordinateRegionMake([lastLocation coordinate], span);

        [_mapView setRegion:region animated:YES];
        [manager stopUpdatingLocation];
    }
}


- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(MKAnnotationView *)annotation
{

    //Zoom back to the user location after adding a new set of annotations.

    //Get the center point of the visible map.
    CLLocationCoordinate2D centre = [mv centerCoordinate];
    NSLog(@"centerCoordinate.Latitude = %f and centerCoordinate.Longitude = %f",centre.latitude, centre.longitude);

//    MKCoordinateRegion region;


    //If this is the first launch of the app then set the center point of the map to the user's location.
    if (firstLaunch) {
        region = MKCoordinateRegionMakeWithDistance(_myLocationMngr.location.coordinate,50000,50000);
        firstLaunch=NO;
    }else {
        //Set the center point to the visible region of the map and change the radius to match the search radius passed to the Google query string.
        region = MKCoordinateRegionMakeWithDistance(centre,currentDist,currentDist);

    }

    //Set the visible region of the map.
    [mv setRegion:region animated:YES];

}


-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    //Get the east and west points on the map so you can calculate the distance (zoom level) of the current map view.
    MKMapRect mRect = self.mapView.visibleMapRect;
    MKMapPoint eastMapPoint = MKMapPointMake(MKMapRectGetMinX(mRect), MKMapRectGetMidY(mRect));
    MKMapPoint westMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), MKMapRectGetMidY(mRect));

    //Set your current distance instance variable.
    currentDist = MKMetersBetweenMapPoints(eastMapPoint, westMapPoint);

    //Set your current center point on the map instance variable.
    currentCentre = self.mapView.centerCoordinate;
    region = MKCoordinateRegionMakeWithDistance(currentCentre,currentDist,currentDist);
}

-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState
{
    MKMapRect mRect = self.mapView.visibleMapRect;
    MKMapPoint eastMapPoint = MKMapPointMake(MKMapRectGetMinX(mRect), MKMapRectGetMidY(mRect));
    MKMapPoint westMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), MKMapRectGetMidY(mRect));

    //Set your current distance instance variable.
    currentDist = MKMetersBetweenMapPoints(eastMapPoint, westMapPoint);

    //Set your current center point on the map instance variable.
    currentCentre = self.mapView.centerCoordinate;
    region = MKCoordinateRegionMakeWithDistance(currentCentre,currentDist,currentDist);
}

- (IBAction)refresh:(id)sender
{
    // might want to use introspection to be sure sender is UIBarButtonItem
    // (if not, it can skip the spinner)
    // that way this method can be a little more generic

    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    [spinner startAnimating];
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:spinner];

    dispatch_queue_t downloadQueue = dispatch_queue_create("meet downloader", NULL);
    dispatch_async(downloadQueue, ^{
        NSArray *meetsWithCoordinates = [MeetFetcher selectedGeoreferencedMeets:_beginningDateForSearch andCompetitionLevel:_levelOfCompetition];
        dispatch_async(dispatch_get_main_queue(), ^{
            self.navigationItem.leftBarButtonItem = sender;
            NSLog(@"meetsWithCoordinates count = %d", [meetsWithCoordinates count]);
//            NSLog(@"%@",meetsWithCoordinates);
            myPinColor = MKPinAnnotationColorPurple;
            self.meets = meetsWithCoordinates;
        });
    });
}

@end

2 个答案:

答案 0 :(得分:0)

你不应该调用didAddAnnotationViews,你应该添加注释,如果它确实添加了注释,让iOS调用委托方法。

每次添加注释视图时,您都在更改区域。我怀疑你每次添加新注释时都打算这样做,所以在addAnnotations的同一个地方添加setRegion调用。视图可能会以不同于预期的顺序添加,例如平移或缩小可能会显示更多注释,从而绘制这些注释的视图。

答案 1 :(得分:0)

所以这是我使用安娜和克雷格的建议学到的。首先,我使用了错误的方法来确定应用是否有权使用位置服务。然后我打开一个开关来确定是否已经设置了初始缩放级别。

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.mapView.delegate = self;

    self.myLocationMngr = [[CLLocationManager alloc] init];
    self.myLocationMngr.delegate = self;
    self.myLocationMngr.desiredAccuracy = 500; // 500 meters.

    if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized) {
        myPinColor = MKPinAnnotationColorGreen;
        [self.myLocationMngr startUpdatingLocation];
        if (!haveSetZoomLevel) {
            CLLocation *currentLocation = [self.myLocationMngr location];
            CLLocationCoordinate2D currentCoordinates = [currentLocation coordinate];
            region = MKCoordinateRegionMakeWithDistance(currentCoordinates,50000,50000);
            [self.mapView setRegion:region animated:YES];
            haveSetZoomLevel = YES;
        }
    }

    //Set some paramater for the location object.
    [self.myLocationMngr setDistanceFilter:kCLDistanceFilterNone];  
    [self.myLocationMngr setDesiredAccuracy:kCLLocationAccuracyBest];

}

然后我用了

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized) {
    // zoom to user's location
    } else {
    // zoom to a default location
    }
}