我已经创建MKMapView
并用于UIBarButtonItem
显示zoom out
所有regions
. 它在 iPhone 模拟器上运行良好,但是当我在设备上尝试时,它zoom
会在 3-5 秒或有时 10 秒后恢复current location
。我不知道这里出了什么问题。感谢您的任何建议。
以下是我的代码
MapViewController.h
#import <UIKit/UIKit.h>
#import "MapListViewController.h"
@class MCLocation;
@interface MapViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate, MapListViewControllerDelegate>
{
CLLocationManager *locationManager;
NSArray *locations;
__weak IBOutlet MKMapView *worldView;
__weak IBOutlet UISegmentedControl *mapTypeControl;
}
@property (nonatomic, strong) MCLocation *item;
@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
- (IBAction)changeMapType:(id)sender;
- (void)zoomLocation:(CLLocationCoordinate2D)i;
@end
MapViewController.m
#import "MapViewController.h"
#import "MCLocation.h"
#import "MCLocationStore.h"
#import "MapDetailViewController.h"
#define METERS_PER_MILE 1609.344
@interface MapViewController ()
@end
@implementation MapViewController
@synthesize item;
@synthesize fetchedResultsController;
@synthesize managedObjectContext;
- (id)init
{
self = [super initWithNibName:@"MapViewController" bundle:nil];
if (self) {
[[self navigationItem] setTitle:@"Map"];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStyleBordered target:self action:nil];
[[self navigationItem] setBackBarButtonItem:backButton];
UIImage *userImage = [UIImage imageNamed:@"User.png"];
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithImage:userImage style:UIBarButtonItemStyleBordered target:self action:@selector(showUser)];
UIImage *locationImage = [UIImage imageNamed:@"Pin.png"];
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithImage:locationImage style:UIBarButtonItemStyleBordered target:self action:@selector(showLocation)];
[[self navigationItem] setLeftBarButtonItems:leftButton];
[[self navigationItem] setRightBarButtonItems:rightButton];
}
return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
return [self init];
}
- (MKCoordinateRegion)regionForAnnotations:(NSArray *)annotations
{
MKCoordinateRegion region;
if ([annotations count] == 0) {
region = MKCoordinateRegionMakeWithDistance(worldView.userLocation.coordinate, 1000, 1000);
} else if ([annotations count] == 1) {
id <MKAnnotation> annotation = [annotations lastObject];
region = MKCoordinateRegionMakeWithDistance(annotation.coordinate, 1000, 1000);
} else {
CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;
CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;
for (id <MKAnnotation> annotation in annotations)
{
topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
}
MKCoordinateSpan span;
span.latitudeDelta = 2.0;
span.longitudeDelta = 0.5;
region.span = span;
region.center = worldView.userLocation.coordinate;
return [worldView regionThatFits:region];
}
- (IBAction)showUser
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(worldView.userLocation.coordinate, 250, 250);
[worldView setRegion:[worldView regionThatFits:region] animated:YES];
}
- (IBAction)showLocation
{
MKCoordinateRegion region = [self regionForAnnotations:locations];
[worldView setRegion:region animated:YES];
}
- (void)updateLocations
{
if (locations != nil) {
[worldView removeAnnotations:locations];
}
locations = [self.fetchedResultsController fetchedObjects];
[worldView addAnnotations:locations];
}
- (void)zoomLocation:(CLLocationCoordinate2D)i
{
CLLocationCoordinate2D zoomLocation = i;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
MKCoordinateRegion adjustedRegion = [worldView regionThatFits:viewRegion];
[worldView setRegion:adjustedRegion animated:YES];
}
- (void)performFetch
{
NSError *error;
if (![self.fetchedResultsController performFetch:&error]) {
FATAL_CORE_DATA_ERROR(error);
return;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[worldView setShowsUserLocation:YES];
[self performFetch];
[self loadMapTypePref];
[self updateLocations];
// If we have locations, then show them on the map. If there are no
// locations, then let the map view figure out how to center on the
// user's position. It will usually do a pretty good job.
if ([locations count] > 0) {
[self showLocation];
}
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
[mapTypeControl setHidden:YES];
CLLocationCoordinate2D coord = [item coordinate];
[worldView setCenterCoordinate:coord animated:NO];
[self zoomLocation:coord];
}
}
- (void)viewDidUnload
{
worldView = nil;
mapTypeControl = nil;
locations = nil;
fetchedResultsController = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc
{
[locationManager setDelegate:nil];
}
#pragma mark - MKMapViewDelegate
- (void)mapView:(MKMapView *)mapView
didUpdateUserLocation:(MKUserLocation *)userLocation
{
CLLocationCoordinate2D loc = [userLocation coordinate];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 250, 250);
[worldView setRegion:region animated:YES];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView
viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *LocationIdentifier = @"Location";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[worldView dequeueReusableAnnotationViewWithIdentifier:LocationIdentifier];
if ([annotation isKindOfClass:[MCLocation class]]) {
if (!annotationView) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:LocationIdentifier];
}
[annotationView setAnnotation:annotation];
[annotationView setPinColor:MKPinAnnotationColorRed];
[annotationView setEnabled:YES];
[annotationView setAnimatesDrop:YES];
[annotationView setCanShowCallout:YES];
[annotationView setCalloutOffset:CGPointMake(-5, 5)];
[annotationView setUserInteractionEnabled:YES];
UIButton *rightButton = nil;
UIImage *logoImage = [UIImage imageNamed:@"monkcup-map-pin.png.png"];
UIImageView *leftButton = [[UIImageView alloc] initWithImage:logoImage];
rightButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[annotationView setRightCalloutAccessoryView:rightButton];
[annotationView setLeftCalloutAccessoryView:leftButton];
return annotationView;
} else {
[[worldView userLocation] setTitle:@"You're here"];
}
return nil;
}
- (void)mapView:(MKMapView *)mapView
annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
// Call out code
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSTimeInterval t = [[newLocation timestamp] timeIntervalSinceNow];
if (t < -180) {
return;
}
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
//
}
#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController
{
if (fetchedResultsController) {
return fetchedResultsController;
}
// Create and configure a fetch request with the Book entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
MCLocationStore *ls = [MCLocationStore sharedStore];
self.managedObjectContext = ls.context;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MCLocation" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Create the sort descriptors array.
NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"storeName" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sd, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Create and initialize the fetch results controller.
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"MapView"];
return fetchedResultsController;
}
@end