我将地图围绕用户的位置居中,或者在缩放级别约为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
答案 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
}
}