I made a count-steps app, I count the steps with the iPhone accelerometer and now I want to display the path I made on a mapView. I can easily show the map and catch the right position with the iPhone GPS, I can display the start and the end point and I can to draw a polyline to show the path I made. Now my problem is how to set a correct zoom on the map? When I open the ViewController with map the zoom it's too far and I've to zoom to see the path I made.
So my question is how to set a correct zoom?
I post here the code of the View Controller with the mapView:
ResultViewController.m
#import "ResultViewController.h"
#import "MapAnnotation.h"
#interface ResultViewController ()
#property (nonatomic, strong)NSMutableArray *mapAnnotation;
#property (nonatomic) BOOL needUpdateRegion;
#end
#implementation ResultViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.labelResult.text = self.totalSteps;
[self.mapView setDelegate:self];
self.needUpdateRegion = YES;
self.mapAnnotation = [[NSMutableArray alloc]initWithCapacity:2];
CLLocation *startLocation = [self.locationArray objectAtIndex:0];
CLLocation *stopLocation = [self.locationArray lastObject];
NSString *startLatitude = [NSString stringWithFormat:#"%f", startLocation.coordinate.latitude];
NSString *startLongitude = [NSString stringWithFormat:#"%f", startLocation.coordinate.longitude];
NSString *stopLatitude = [NSString stringWithFormat:#"%f", stopLocation.coordinate.latitude];
NSString *stopLongitude = [NSString stringWithFormat:#"%f", stopLocation.coordinate.longitude];
MapAnnotation *startPlace = [[MapAnnotation alloc]initWithCoordinate:startLatitude andLong:startLongitude];
MapAnnotation *stopPlace = [[MapAnnotation alloc]initWithCoordinate:stopLatitude andLong:stopLongitude];
[self.mapAnnotation insertObject:startPlace atIndex:0];
[self.mapAnnotation insertObject:stopPlace atIndex:1];
if (self.mapAnnotation) {
[self.mapView removeAnnotations:self.mapView.annotations];
}
[self.mapView addAnnotation:self.mapAnnotation[0]];
[self.mapView addAnnotation:self.mapAnnotation[1]];
[self updateRegion];
[self createMKpolylineAnnotation];
}
- (void)updateRegion
{
self.needUpdateRegion = NO;
CGRect boundingRect;
BOOL started = NO;
for (id <MKAnnotation> annotation in self.mapView.annotations) {
CGRect annotationRect = CGRectMake(annotation.coordinate.latitude, annotation.coordinate.longitude, 0, 0);
if (!started) {
started = YES;
boundingRect = annotationRect;
} else {
boundingRect = CGRectUnion(boundingRect, annotationRect);
}
}
if (started) {
boundingRect = CGRectInset(boundingRect, -0.2, -0.2);
if ((boundingRect.size.width < 20) && (boundingRect.size.height < 20)) {
MKCoordinateRegion region;
region.center.latitude = boundingRect.origin.x + boundingRect.size.width / 2;
region.center.longitude = boundingRect.origin.y + boundingRect.size.height / 2;
region.span.latitudeDelta = boundingRect.size.width;
region.span.longitudeDelta = boundingRect.size.height;
[self.mapView setRegion:region animated:YES];
}
}
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay {
MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
polylineView.strokeColor = [UIColor blueColor];
polylineView.lineWidth = 5.0;
return polylineView;
}
- (void)createMKpolylineAnnotation {
NSInteger numberOfSteps = self.locationArray.count;
CLLocationCoordinate2D *coords = malloc(sizeof(CLLocationCoordinate2D) * numberOfSteps);
for (NSInteger index = 0; index < numberOfSteps; index++) {
CLLocation *location = [self.locationArray objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coords[index] = coordinate;
}
MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coords count:numberOfSteps];
[self.mapView addOverlay:polyLine];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)restart:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
What's wrong with this code? There's someone that can help me to zoom the map correctly?
Thank you
In that case I would recommend you to call the following method in order to zoom to a region of the map, you could add the call at the end your method - (void)createMKpolylineAnnotation;
Call:
[self zoomToPolyLine: self.mapView polyLine:polyLine animated:YES];
Method:
-(void)zoomToPolyLine:(MKMapView*)map polyLine:(MKPolyline*)polyLine
animated:(BOOL)animated
{
MKPolygon* polygon = [MKPolygon polygonWithPoints:polyLine.points count:polyLine.pointCount];
[map setRegion:MKCoordinateRegionForMapRect([polygon boundingMapRect])
animated:animated];
}
firstly add this line in view did load after you set the mapview delegate as
[self.mapView setDelegate:self];
self.needUpdateRegion = YES;
mapView.zoomEnabled = YES;
mapView.scrollEnabled = YES;
....
}
then modify the below line to set the zoom level as required by you 60000=60 km..
[mapView setRegion: MKCoordinateRegionMakeWithDistance(site.coordinate, 60000, 60000) animated:YES];
or you can try this method for setting scale of zoom as
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context {
CGImageRef imageReference = self.overlayImage.CGImage;
MKMapRect theMapRect = self.overlay.boundingMapRect;
CGRect theRect = [self rectForMapRect:theMapRect];
CGContextScaleCTM(context, 1.0, -1.0);
CGContextTranslateCTM(context, 0.0, -theRect.size.height);
CGContextDrawImage(context, theRect, imageReference);
}
hope this helps you..Cheers!!
Related
I am using OCMapView in my project . OCMapView is Map Kit cluster pinpoints.
I want to add line on mapkit. like this
But my code doing this : it's not logical add to overlay line on map .
I handle this code .
CLLocationCoordinate2D *coordinates
= malloc(sizeof(CLLocationCoordinate2D) * [self.mapView.annotations count]);
for (int i=0; i<[self.mapView.annotations count]; i++) {
OCMapViewSampleHelpAnnotation * ann=[annodationArray objectAtIndex:i];
coordinates[i]=ann.coordinate;
}
self.routeLineView=nil;
self.routeLine = [MKPolyline polylineWithCoordinates:coordinates count:self.mapView.annotations.count]; //
free(coordinates);
[self.mapView setVisibleMapRect:[self.routeLine boundingMapRect]]; //If you want the route to be visible
dispatch_async(dispatch_get_main_queue(), ^{
[self.mapView addOverlay:self.routeLine];
});
you can see my overlay delagate method
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay{
//normally here is circle.
if(overlay == self.routeLine)
{
if(nil == self.routeLineView)
{
self.routeLineView = [[MKPolylineView alloc] initWithPolyline:self.routeLine];
self.routeLineView.fillColor = [UIColor redColor];
self.routeLineView.strokeColor = [UIColor redColor];
self.routeLineView.lineWidth = 3;
}
return self.routeLineView;
}
return nil;
}
also I am sharing my project code . How can I solve this problem ?
https://www.dropbox.com/s/q0gtwihtl8o2pom/OCMapView-master.zip
Just use self.mapView.displayedAnnotations (these are only the ones visible) instead of self.mapView.annotations (these are all annotations, that were added).
I have been building an app which draw the lines of the current user moving along the map. Now, in iOS5 when I add the overlay to the mapview, it justs add it directly, in iOS6 it adds the overlay with "fade in" animation. I don't want this annoying animation. I also have a function which plays the trail upon the coordinates saved (after the user is done running or walking), when I play this, the lines flicker very fast, just because of this animation. This is really annoying and I really would appreciate any guidance or a solution to get rid of this animation.
Code for adding overlays:
MKMapPoint *pointsArray = malloc(sizeof(CLLocationCoordinate2D)*2);
pointsArray[0]= MKMapPointForCoordinate(oldLocation.coordinate);
pointsArray[1]= MKMapPointForCoordinate(newLocation.coordinate);
self.routeLine = [MKPolyline polylineWithPoints:pointsArray count:2];
free(pointsArray);
[self.mapView addOverlay:self.routeLine];
Code for displaying overlay:
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay{
MKOverlayView *overlayView = nil;
MKPolylineView *routeLineView = [[MKPolylineView alloc] initWithPolyline:(MKPolyline *)overlay];
routeLineView.fillColor = [UIColor blueColor];
routeLineView.strokeColor = [UIColor blueColor];
routeLineView.backgroundColor = [UIColor clearColor];
routeLineView.lineWidth = 10;
routeLineView.lineCap = kCGLineCapRound;
overlayView = routeLineView;
return overlayView;
}
Thanks!
EDIT:
Code for going through the path:
playTimer = [NSTimer scheduledTimerWithTimeInterval:interval
target:self
selector:#selector(playPathTimer)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:playTimer forMode:NSRunLoopCommonModes];
- (void)playPathTimer{
MKMapPoint *pointsArray = malloc(sizeof(CLLocationCoordinate2D) * 2);
double latitude1 = ((WorldPoint *)[coordsArray objectAtIndex:playCounter]).latitude.doubleValue;
double longitude1 = ((WorldPoint *)[coordsArray objectAtIndex:playCounter]).longitude.doubleValue;
double latitude2 = ((WorldPoint *)[coordsArray objectAtIndex:playCounter+nextCord]).latitude.doubleValue;
double longitude2 = ((WorldPoint *)[coordsArray objectAtIndex:playCounter+nextCord]).longitude.doubleValue;
CLLocation *location1 = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude1, longitude1)
altitude:0
horizontalAccuracy:0
verticalAccuracy:0
timestamp:[NSDate date]];
CLLocation *location2 = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude2, longitude2)
altitude:0
horizontalAccuracy:0
verticalAccuracy:0
timestamp:[NSDate date]];
pointsArray[0] = MKMapPointForCoordinate(location1.coordinate);
pointsArray[1] = MKMapPointForCoordinate(location2.coordinate);
self.routeLine = [MKPolyline polylineWithPoints:pointsArray count:2];
free(pointsArray);
[self.mapView addOverlay:self.routeLine];
[playRouteLines addObject:self.routeLine];
// self.mapView.centerCoordinate = CLLocationCoordinate2DMake(latitude1, longitude1);
playCounter = playCounter + nextCord;
if(playCounter + nextCord >= coordsArray.count){
// [displayLink setPaused:YES];
// [displayLink invalidate];
[playTimer invalidate];
playTimer = nil;
playCounter = 0;
[self showStartAndEndFlags];
if(ee.trail.checkpoint.count > 0){
[self showCheckpoints];
}
self.playButton.enabled = YES;
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:[self getRegionWithCorrectZooming]];
[self.mapView setRegion:adjustedRegion animated:YES];
}
}
Instead of using a MKPolylineView you can use your own subclass of MKOverlayView (superclass of MKPolylineView) and then override drawMapRect:zoomScale:inContext: where you draw the lines yourself.
I guess with this you won't have any fade in animation (I'm using it and never noticed any animation).
Try the following code for your drawMapRect:zoomScale:inContext: implementation.
You need to create the properties lineColor(CGColor) and lineWidth (CGFloat).
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context {
MKPolyline *polyline = self.overlay;
CGContextSetStrokeColorWithColor(context, self.lineColor);
CGContextSetLineWidth(context, self.lineWidth/zoomScale);
CGMutablePathRef path = CGPathCreateMutable();
CGPoint *points = malloc(sizeof(CGPoint)*polyline.pointCount);
for (int i=0; i<polyline.pointCount; i++) {
points[i] = [self pointForMapPoint:polyline.points[i]];
}
CGPathAddLines(path, NULL, points, polyline.pointCount);
CGContextAddPath(context, path);
CGContextDrawPath(context, kCGPathStroke);
CGPathRelease(path);
free(points);
}
I'm trying to add MKPolyLine to my mapView. But got error: NSInvalidArgumentException', reason: '-[MKPolylineView boundingMapRect]
My code:
- (void)addRoad {
[self loadRoude];
[self.mapView addOverlay:self.routeLine];
}
- (void)loadRoude{
MKMapPoint northEastPoint = MKMapPointForCoordinate(self.mapView.userLocation.coordinate);
MKMapPoint southWestPoint = MKMapPointMake(52.142391, 21.055641);
MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) * 2);
pointArr[0] = northEastPoint;
pointArr[1] = southWestPoint;
self.routeLine = [MKPolyline polylineWithPoints:pointArr count:2];
_routeRect = MKMapRectMake(southWestPoint.x, southWestPoint.y, northEastPoint.x - southWestPoint.x, northEastPoint.y - southWestPoint.y);
free(pointArr);
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MKOverlayView* overlayView = nil;
if(overlay == self.routeLine)
{
if(nil == self.routeLineView)
{
self.routeLineView = [[MKPolylineView alloc] initWithPolyline:self.routeLine];
self.routeLineView.fillColor = [UIColor redColor];
self.routeLineView.strokeColor = [UIColor redColor];
self.routeLineView.lineWidth = 3;
}
overlayView = self.routeLineView;
}
return overlayView;
}
There is my problem?
EDIT
NSLog of self.routeLineView shows me : outeLiveView = <MKPolylineView: 0x7c956d0; frame = (0 0; 0 0); opaque = NO; layer = <MKOverlayClusterProxyLayer: 0x7c97eb0>> Is this normal?
EDIT2
NSLog(#"pointArr[0]x = %f",pointArr[0].x);
NSLog(#"pointArr[0]y = %f",pointArr[0].y);
NSLog(#"pointArr[1]x = %f",pointArr[1].x);
NSLog(#"pointArr[1]y = %f",pointArr[1].y);
show:
pointArr[0]x = 149891376.014222
pointArr[0]y = 88510604.996837
pointArr[1]x = 149917951.870020
pointArr[1]y = 88495551.883086
That mean my pointers array have no nil objects. I'm really in shock
From Apple's documentation:
NSInvalidArgumentException: Name of an exception that occurs when you
pass an invalid argument to a method, such as a nil pointer where a
non-nil object is required. Available in Mac OS X v10.0 and later.
Check the values you are using to initialize routeLineView or any other MKPolylineView objects. One is probably nil.
I'm Trying to develop an UIScrollView Based Image gallery.
So let me explain what i'm trying to achieve here:
I want to a sliding presentation, that can show upto 140 image. ( You can swipe back and forth )
I've found information on the web, and i've been told the best way to do this is with a UIScrollview which has 3 UIImageViews which you create and remove from superview.
So i managed to create such a "sliding image gallery" with some help from a few tutorials :).
I've managed to upload the application to the ipad, start up the application and run it.
after i viewed about 50-70 slides the app crashes ( out of memory). My knowledge of Obj. C isn't that great .
You'll find the code below: it Prob. has something to do with releasing the images.
Improvements to the code would be really helpful
#import "ParatelPresentationViewController.h"
//Define the UIView ( we need 3 Image Views left, mid right);
#interface SlideShowView : UIView
{
NSArray * mImages;
UIImageView * mLeftImageView;
UIImageView * mCurrentImageView;
UIImageView * mRightImageView;
NSUInteger mCurrentImage;
BOOL mSwiping;
CGFloat mSwipeStart;
}
- (id)initWithImages:(NSArray *)inImages;
#end // SlideShowView
#pragma mark -
#implementation SlideShowView
- (UIImageView *)createImageView:(NSUInteger)inImageIndex
{
if (inImageIndex >= [mImages count])
{
return nil;
}
UIImageView * result = [[UIImageView alloc] initWithImage:[mImages objectAtIndex:inImageIndex]];
result.opaque = YES;
result.userInteractionEnabled = NO;
result.backgroundColor = [UIColor blackColor];
result.contentMode = UIViewContentModeScaleAspectFit;
result.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight ;
return result;
}
- (id)initWithImages:(NSArray *)inImages
{
if (self = [super initWithFrame:CGRectZero])
{
mImages = [inImages retain];
NSUInteger imageCount = [inImages count];
NSLog(#"hoeveel foto's: %i");
if (imageCount > 0)
{
mCurrentImageView = [self createImageView:0];
[self addSubview:mCurrentImageView];
if (imageCount > 1)
{
mRightImageView = [self createImageView:1];
[self addSubview:mRightImageView];
}
}
self.opaque = YES;
self.backgroundColor = [UIColor blueColor];
self.contentMode = UIViewContentModeScaleAspectFit;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
return self;
}
- (void)dealloc
{
[mImages release];
[super dealloc];
}
- (void)layoutSubviews
{
if (mSwiping)
return;
//CGSize contentSize = self.frame.size; // Enable when you use content.width/height
//self.backgroundColor = [UIColor redColor];
mLeftImageView.frame = CGRectMake(-1024, 0.0f, 1024, 748);// (-1024, 0.0f, 1024, 748) can be replaced by (-contentSize.width, 0.0f, contentSize.width, contentSize.height);
mCurrentImageView.frame = CGRectMake(0.0f, 0.0f, 1024, 748);
mRightImageView.frame = CGRectMake(1024, 0.0f, 1024, 748);
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count] != 1)
return;
mSwipeStart = [[touches anyObject] locationInView:self].x;
mSwiping = YES;
mLeftImageView.hidden = NO;
mCurrentImageView.hidden = NO;
mRightImageView.hidden = NO;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if (! mSwiping || [touches count] != 1)
return;
CGFloat swipeDistance = [[touches anyObject] locationInView:self].x - mSwipeStart;
//CGSize contentSize = self.frame.size;
mLeftImageView.frame = CGRectMake(swipeDistance - 1024, 0.0f, 1024, 748);
mCurrentImageView.frame = CGRectMake(swipeDistance, 0.0f, 1024, 748);
mRightImageView.frame = CGRectMake(swipeDistance + 1024, 0.0f, 1024, 748);
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (! mSwiping)
return;
//CGSize contentSize = self.frame.size;
NSUInteger count = [mImages count];
CGFloat swipeDistance = [[touches anyObject] locationInView:self].x - mSwipeStart;
if (mCurrentImage > 0 && swipeDistance > 50.0f)
{
mRightImageView.image = nil;
//[mRightImageView.image release];
[mRightImageView removeFromSuperview];
[mRightImageView release];
//mRightImageView = nil;
//NSLog(#"Count of mRight : %i",[mRightImageView retainCount]);
mRightImageView = mCurrentImageView;
mCurrentImageView = mLeftImageView;
mCurrentImage--;
if (mCurrentImage > 0)
{
mLeftImageView = [self createImageView:mCurrentImage - 1];
mLeftImageView.hidden = YES;
[self addSubview:mLeftImageView];
}
else
{
mLeftImageView = nil;
}
}
else if (mCurrentImage < count - 1 && swipeDistance < -50.0f)
{
mLeftImageView.image = nil;
//[mLeftImageView.image release];
[mLeftImageView removeFromSuperview];
[mLeftImageView release];
//mLeftImageView = nil;
mLeftImageView = mCurrentImageView;
mCurrentImageView = mRightImageView;
mCurrentImage++;
if (mCurrentImage < count - 1)
{
mRightImageView = [self createImageView:mCurrentImage + 1];
mRightImageView.hidden = YES;
[self addSubview:mRightImageView];
NSLog(#"Count of mRight : %i",[mRightImageView.image retainCount]);
}
else
{
mRightImageView = nil;
}
}
[UIView beginAnimations:#"swipe" context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.3f];
mLeftImageView.frame = CGRectMake(-1024, 0.0f, 1024, 748);
mCurrentImageView.frame = CGRectMake(0.0f, 0.0f, 1024, 748);
mRightImageView.frame = CGRectMake(1024, 0.0f, 1024, 748);
[UIView commitAnimations];
mSwiping = NO;
}
#end // SlideShowView
#pragma mark -
#implementation ParatelPresentationViewController
- (id)init
{
if (self = [super initWithNibName:nil bundle:nil])
{
NSMutableArray *Displayimages = [[NSMutableArray alloc]init];
int i;
for(i=0 ; i<139 ; i++) {
NSString *tempString = [NSString stringWithFormat:#"Dia%d", i+1];
NSLog(#"Dia%d.jpg", i+1);
NSString *imageFile = [[NSBundle mainBundle] pathForResource:tempString ofType:#"JPG"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:imageFile];
if (fileExists){
[Displayimages addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:tempString ofType:#"JPG"]]];
NSLog(#"img");
}else {
break;
}
}
//NSArray * images = [NSArray arrayWithObjects:[UIImage imageNamed:#"1.jpg"], [UIImage imageNamed:#"2.jpg"], [UIImage imageNamed:#"3.jpg"], [UIImage imageNamed:#"4.jpg"], [UIImage imageNamed:#"5.jpg"], nil];
//NSLog(#"Objects Img = %#", images);
NSLog(#"Images %#",Displayimages);
self.view = [[[SlideShowView alloc] initWithImages:Displayimages] autorelease];
[Displayimages release];
}
return self;
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
//return YES;
return UIInterfaceOrientationIsLandscape (interfaceOrientation);
}
#end
If you would find a solution or tips, all are welcome !
Thanks in advance
kind regards Bart !
You definitely have a memory leak in createImageView:. You will have to change
return result;
to
return [result autorelease];
There might be more leaks, but that's an obvious one.
Johannes
So I've got a bunch of annotations spread out on my map... everything is just dandy. Now I need to be able to set the map's position and zoom so they all fit perfectly. How can I do this?
From Apple forums...
- (void)recenterMap {
NSArray *coordinates = [self.mapView valueForKeyPath:#"annotations.coordinate"];
CLLocationCoordinate2D maxCoord = {-90.0f, -180.0f};
CLLocationCoordinate2D minCoord = {90.0f, 180.0f};
for(NSValue *value in coordinates) {
CLLocationCoordinate2D coord = {0.0f, 0.0f};
[value getValue:&coord];
if(coord.longitude > maxCoord.longitude) {
maxCoord.longitude = coord.longitude;
}
if(coord.latitude > maxCoord.latitude) {
maxCoord.latitude = coord.latitude;
}
if(coord.longitude < minCoord.longitude) {
minCoord.longitude = coord.longitude;
}
if(coord.latitude < minCoord.latitude) {
minCoord.latitude = coord.latitude;
}
}
MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}};
region.center.longitude = (minCoord.longitude + maxCoord.longitude) / 2.0;
region.center.latitude = (minCoord.latitude + maxCoord.latitude) / 2.0;
region.span.longitudeDelta = maxCoord.longitude - minCoord.longitude;
region.span.latitudeDelta = maxCoord.latitude - minCoord.latitude;
[self.mapView setRegion:region animated:YES];
}
#interface MKMapView (zoomToFit)
- (void)zoomToFitOverlays; //Animation defaults to YES
- (void)zoomToFitOverlay:(id<MKOverlay>)anOverlay;
- (void)zoomToFitOverlays:(NSArray *)someOverlays;
- (void)zoomToFitOverlaysAnimated:(BOOL)animated;
- (void)zoomToFitOverlay:(id<MKOverlay>)anOverlay animated:(BOOL)animated;
- (void)zoomToFitOverlays:(NSArray *)someOverlays animated:(BOOL)animated;
- (void)zoomToFitOverlays:(NSArray *)someOverlays animated:(BOOL)animated insetProportion:(CGFloat)insetProportion; //inset 0->1, defaults in other methods to .1 (10%)
#end
#implementation MKMapView (zoomToFit)
#pragma mark -
#pragma mark Zoom to Fit
- (void)zoomToFitOverlays {
[self zoomToFitOverlaysAnimated:YES];
}
- (void)zoomToFitOverlay:(id<MKOverlay>)anOverlay {
[self zoomToFitOverlay:[NSArray arrayWithObject:anOverlay] animated:YES];
}
- (void)zoomToFitOverlays:(NSArray *)someOverlays {
[self zoomToFitOverlays:someOverlays animated:YES];
}
- (void)zoomToFitOverlaysAnimated:(BOOL)animated {
[self zoomToFitOverlays:self.overlays animated:animated];
}
- (void)zoomToFitOverlay:(id<MKOverlay>)anOverlay animated:(BOOL)animated {
[self zoomToFitOverlays:[NSArray arrayWithObject:anOverlay] animated:YES];
}
- (void)zoomToFitOverlays:(NSArray *)someOverlays animated:(BOOL)animated {
[self zoomToFitOverlays:someOverlays animated:animated insetProportion:.1];
}
- (void)zoomToFitOverlays:(NSArray *)someOverlays animated:(BOOL)animated insetProportion:(CGFloat)insetProportion {
//Check
if ( !someOverlays || !someOverlays.count ) {
return;
}
//Union
MKMapRect mapRect = MKMapRectNull;
if ( someOverlays.count == 1 ) {
mapRect = ((id<MKOverlay>)someOverlays.lastObject).boundingMapRect;
} else {
for ( id<MKOverlay> anOverlay in someOverlays ) {
mapRect = MKMapRectUnion(mapRect, anOverlay.boundingMapRect);
}
}
//Inset
CGFloat inset = (CGFloat)(mapRect.size.width*insetProportion);
mapRect = [self mapRectThatFits:MKMapRectInset(mapRect, inset, inset)];
//Set
MKCoordinateRegion region = MKCoordinateRegionForMapRect(mapRect);
[self setRegion:region animated:animated];
}
#end