2014-01-09 87 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 
    } 
}