2014-01-09 44 views
0

我正围绕用户位置或放大缩小级别大约为30英里的默认位置围绕地图。问题是我可以放大,但不能缩小。MKMapView不会缩小

每当我尝试缩小我的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 
+0

每次调用setRegion之前,把一个NSLog的说: “从调用方法XYZ ... setRegion”。在尝试缩小后查看哪一个会触发。 – Anna

+0

好的建议,谢谢安娜。 – PhillipOReilly

回答

0

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

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

+0

这样做,谢谢! – PhillipOReilly

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 
    } 
}