
seen from Netherlands

seen from Malaysia

seen from Hungary
seen from Türkiye

seen from United Kingdom
seen from Japan

seen from United States

seen from Sweden
seen from China

seen from Italy

seen from Italy

seen from Germany

seen from Italy
seen from Spain

seen from Italy
seen from China
seen from China

seen from Italy
seen from China

seen from Ireland

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
Adding Maps to the App - part 2
One thing is left a subtlety, (perhaps because of the way we have presented it) is the following :
Showing the user's location on a map on the iPhone is fundamentally TWO PROCESSES, not one. The first - Getting the users location - information about where the real users is located on the real world we all live in. The second - Displaying the users location - that pin(avatar) that represents the user, in the map on the phone(virtual world) that represents the real world we all live in.
So we use two frameworks from the SDK, CoreLocation and MapKit.
We set two properties on our View Controller - a CLLocationManager, and an IBOutlet to a MKMapView. We also set our view controller to be the delegate of both the MKMapView and the CLLocationManager making sure that we have added the protocols in our header file. Having done this, we can respond to events whenever we get location updates. As always, please read the documentation for more information about more delegate methods.
In our viewDidLoad we start updating location on our location manager. Next on our MKMapView, we set showsUserLocation. We also set other properties on the view controller, however they are not so interesting and we shall skip on the details. So every time the location updates, showsUserLocation changes the pin to the appropriate place on the map.
We do other things manually, like panning and zooming the map to the location of the user. This done using the map view delegate methods. mapView: DidUpdateUserLocation: is whether we put our zooming and panning code.
What else is left to talk about? Oh yes! One thing to take special care of is stopping location updates from the location manager. Location updates are very power intensive and users will drain the batteries out very easily while using the app. And then no one will want to use our app. So, we have to devise an algorithm or even a plan to start and stop location updates. Location updates are stopped by calling stopUpdatingLocation on the location manager, just like location updates are started by calling startUpdatingLocation on the location manager.
How to Customize Map Annotation and Map Annotation View
Many developers might have seen iOS app like yelp, foursquare, they have their own very customized Annotation View providing very specific information.
While, in this demo, it will show you how to make your own map annotation and annotation view.
1st, create a new project, name it "Tracker 286s".
2nd, Add MapKit framework to your project. (It's under Build Phases of your project target).
3rd, Go to your storyboard, drag a toolbar and MKMapView to the your controller's view. The clear button will clear all the annotation from the map.
4th, Ctrl + drag your MapView outlet to the ViewController.m, also ctrl + drag the clear(Bar Button Item) to add the IBAction to the ViewController.m
5th, Add
@import MapKit;
in the ViewController.m file.
6th, Add <MKMapViewDelegate> right after
@interface ViewController ()
To create an Annotation to be added to the MapView, we need to create a class conforms MKAnnotation Protocol.
7th, Create a new file names MAnnotation subclass of NSObject, conforms <MKAnnotation>.
// // MAnnotation.h // Tracke 286s // // Created by Antonio081014 on 4/7/14. // Copyright (c) 2014 Antonio081014.com. All rights reserved. // #import <Foundation/Foundation.h> @import MapKit; @interface MAnnotation : NSObject <MKAnnotation> @property (nonatomic, strong) NSNumber *angle; - (id)initWithLocation:(CLLocationCoordinate2D)coord andAngle:(CGFloat) angle; @end
In this code, we have a public property angle, which will be used and explained later. Also a public designate initializer is declared, which contains a coordinate tells where in the map the annotation will be, and the angle.
8th, Implement the function in MAnnotation File.
// // MAnnotation.m // Tracke 286s // // Created by Antonio081014 on 4/7/14. // Copyright (c) 2014 Antonio081014.com. All rights reserved. // #import "MAnnotation.h" @implementation MAnnotation @synthesize coordinate = _coordinate; @synthesize title = _title; @synthesize subtitle = _subtitle; - (id)initWithLocation:(CLLocationCoordinate2D)coord andAngle:(CGFloat)angle { self = [super init]; if (self) { self.coordinate = coord; self.angle = [NSNumber numberWithDouble:angle]; } return self; } #define epsilon 0.005f - (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate { if ((fabs(_coordinate.latitude - newCoordinate.latitude) > epsilon || fabs(_coordinate.longitude - newCoordinate.longitude) > epsilon)) { [self willChangeValueForKey:@"coordinate"]; _coordinate = newCoordinate; [self didChangeValueForKey:@"coordinate"]; } } - (CLLocationCoordinate2D)coordinate { return _coordinate; } - (void)setTitle:(NSString *)title { if (_title != title) { [self willChangeValueForKey:@"title"]; _title = title; [self didChangeValueForKey:@"title"]; } } - (NSString *)title { if (_title) { return _title; } return _title = [NSString stringWithFormat:@"%.6f", [self.angle doubleValue]]; } - (NSString *)subtitle { if (_subtitle) { return _subtitle; } return _subtitle = [NSString stringWithFormat:@"(%.5f, %.5f)", self.coordinate.longitude, self.coordinate.latitude]; } - (void)setSubtitle:(NSString *)subtitle { if (_subtitle != subtitle) { [self willChangeValueForKey:@"subtitle"]; _subtitle = subtitle; [self didChangeValueForKey:@"subtitle"]; } } @end
Here, implement all the properties of the MKAnnotation, since the Map-Kit uses KVO(Key-Value-Observation) to detect any change of property in MKAnnotation, so when we custom implemented these setters, we need to notify the observers(the one who is interested in these changes) in these setters. Any manual change in your change will require you implementing the corresponding setter. For more reference, check out this link. The title and subtitle are used to display callout, which will be displayed when you click on the annotation on the map.
9th, Display annotation on the Map.
// // ViewController.m // Tracke 286s // // Created by Antonio081014 on 4/7/14. // Copyright (c) 2014 Antonio081014.com. All rights reserved. // #import "ViewController.h" @import MapKit; #import "MAnnotation.h" @interface ViewController () <MKMapViewDelegate> @property (weak, nonatomic) IBOutlet MKMapView *mapView; @end @implementation ViewController #define METERS_PER_MILE 1609.344 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // Set the center of the map. // This is the Park near Los Angeles City Hall. CLLocationCoordinate2D centerLocation; centerLocation.latitude = 34.0528873; centerLocation.longitude = -118.2434255; // Create a Map Region based on the Center Location created above and the size defined below. MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(centerLocation, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE); // Set the Map Region to display. [self.mapView setRegion:viewRegion animated:YES]; // Create the coordinate for the Annotation. // This is the location of Los Angeles City Hall, which could be fetched from Google Map. CLLocationCoordinate2D coordinateOfLACityHall; coordinateOfLACityHall.latitude = 34.053714; coordinateOfLACityHall.longitude = -118.242653; // Create the Annotation with our designate initializer. MAnnotation *annotation = [[MAnnotation alloc] initWithLocation:coordinateOfLACityHall andAngle:90.f]; // Add the annotation to the Map. [self.mapView addAnnotation:annotation]; } - (IBAction)clearAllAnnotations:(UIBarButtonItem *)sender { } @end
Most of the code are already explained in the comment around the code. You should get something like this:
When click on the red pin point, you should see:
Which displays the angle as the title, coordinate as the subtitle as we defined in our MAnnotation class.
10th, Custom Annotation View. Adding this snippet to your ViewController.m file.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { return nil; }
This function will be like this even you don't write it here. It's a default delegate function.
11th, Create a new file MAnnotationView subclass MKAnnotationView. So the MAnnotationView.h file will look like:
// // MAnnotationView.h // Tracke 286s // // Created by Antonio081014 on 4/7/14. // Copyright (c) 2014 Antonio081014.com. All rights reserved. // #import <MapKit/MapKit.h> @interface MAnnotationView : MKAnnotationView @end
12th, Implement the designate initializer which will be called in the
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation;
So with other function.
// // MAnnotationView.m // Tracke 286s // // Created by Antonio081014 on 4/7/14. // Copyright (c) 2014 Antonio081014.com. All rights reserved. // #import "MAnnotationView.h" #import "MAnnotation.h" @implementation MAnnotationView - (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; if (self) { // Set the frame size to the appropriate values. CGRect cFrame = self.frame; cFrame.size.width = 40; cFrame.size.height = 40; self.frame = cFrame; self.contentMode = UIViewContentModeRedraw; // The opaque property is YES by default. Setting it to // NO allows map content to show through any unrendered parts of your view. self.opaque = NO; } return self; } // This function is critical, the comment is very important. // Whenever you assign an annotation to this view, the view will be redraw. - (void)setAnnotation:(id <MKAnnotation>)annotation { [super setAnnotation:annotation]; // this annotation view has custom drawing code. So when we reuse an annotation view // (through MapView's delegate "dequeueReusableAnnoationViewWithIdentifier" which returns non-nil) // we need to have it redraw the new annotation data. // // for any other custom annotation view which has just contains a simple image, this won't be needed // [self setNeedsDisplay]; } // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. // This function simply draw a triangle, then rotate in proper angle. - (void)drawRect:(CGRect)rect { CGFloat angle = 0.f; if ([self.annotation isKindOfClass:[MAnnotation class]]) { MAnnotation *annotation = (MAnnotation *)self.annotation; angle = [annotation.angle doubleValue]; } CGFloat size = MIN(self.bounds.size.width, self.bounds.size.height) / 2.f; CGPoint center = CGPointMake(self.bounds.size.width / 2.f, self.bounds.size.height / 2.f); // Draw the Path. UIBezierPath *path = [[UIBezierPath alloc] init]; [path moveToPoint:CGPointMake(center.x + 0.f, center.y - size)]; [path addLineToPoint:CGPointMake(center.x - size / 2.f, center.y + size / 2.f * sqrt(3.f))]; [path addLineToPoint:CGPointMake(center.x + size / 2.f, center.y + size / 2.f * sqrt(3.f))]; [path closePath]; // Rotate to the right angle. CGAffineTransform transform = CGAffineTransformIdentity; [path applyTransform:transform]; transform = CGAffineTransformTranslate(transform, center.x, center.y); transform = CGAffineTransformRotate(transform, angle / 180.f * M_PI); transform = CGAffineTransformTranslate(transform, -center.x, -center.y); [path applyTransform:transform]; // Fill and Stroke with right color. [[UIColor redColor] setFill]; [[UIColor blackColor] setStroke]; [path fill]; [path stroke]; } @end
Most of the code are explained with the comment.
13, Back to the ViewController.m file, Add the following code right after [super viewWillAppear:animated];
self.mapView.delegate = self;
14, Add the following code to the ViewController.m file.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { // If this annotation is our custom define annotation, we'll display it in our custom annotation view. if ([annotation isKindOfClass:[MAnnotation class]]) { static NSString *annotationViewIdentifier = @"Custom Annotation View"; // We retrieve this annotation view. MKAnnotationView *annotationView = [self.mapView dequeueReusableAnnotationViewWithIdentifier:annotationViewIdentifier]; // If it has been used before, we update the annotation information, so the view could be redraw. if (annotationView) { annotationView.annotation = (MAnnotation *)annotation; } // Otherwise, let's create it. else { annotationView = [[MAnnotationView alloc] initWithAnnotation:(MAnnotation *)annotation reuseIdentifier:annotationViewIdentifier]; annotationView.opaque = NO; } return annotationView; } // Otherwise, will use annotation's default annotation view to display it. // For user current location, it will be a blue twinkle ball. // For other location, it will be a red point pin. return nil; }
Build and Run this code, you will see:
15th, For last, we'll remove the annotations from the Map by implement
- (IBAction)clearAllAnnotations:(UIBarButtonItem *)sender
Adding this snippet in this function:
[self.mapView removeAnnotations:self.mapView.annotations];
If you have more question about removing annotations from MapView, check out another post.
For the full code, check out the github.
How to Remove All the Map Annotations except Current User Location Annotation
Today, working on the project focused on Location and Map View Programming. I need to update the Map Annotation Display when user zoom in and out the map. This would totally make sense here the Annotation will not be resizable and too many of the Annotations displayed in a very small area on the Map. It's like this April Fool's Day, Google Map on mobile device gave people the fun of being a Pokemon Master by finding all the Pokemon, which is displayed as an Annotation on the map. It could be seen only when certain zoom level you are in. So, to find all the Pokemon, you have to zoom to certain level, then search it manually like a tank. So, the question here is how can we remove these MKAnnotations. This task is very easy by using one line code:
[self.mapView removeAnnotations:self.mapView.annotations];
The mapView is the outlet connected with MKMapView in the storyboard. But this line of code would remove all of the annotations on the map. While my app intentionally need to keep the current user location's annotation to constantly display the current location of the user. How can we do that? We need to iterate through all the annotations, find out which one is not the Current User Location Annotation.
for (id<MKAnnotation> annotation in self.mapView.annotations) { if (![annotation isKindOfClass:[MKUserLocation class]]) { [self.mapView removeAnnotation:annotation]; } }
Simple solution. Good luck with your own project.
CCHMapClusterController - High-performance map clustering with MapKit for iOS and OS X. Integrate with 4 lines of code.

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
MKMapView and zoomLevel
While searching for a fix / workaround for this MKMapView bug, I found a couple of useful pieces of code, that allow you to directly manipulate the zoom level of a MKMapView:
Get the zoom level of a map view.
Set the zoom level of a map view.
Here's the code from the above links, combined into a handy MKMapView category:
Making Pins and Callouts in Apple Maps Accessible
Pins (aka location markers) and Callouts on instances of MKMapView are not automatically accessible to blind users via iOS's VoiceOver feature. The impact of this is that while blind users may be able to load your app's map they won't be able to find any of the content that you've placed on the map. Thankfully, there's an easy fix for this using the stock Accessibility framework that Apple provides in iOS.
Update your MKMapViewDelegate's callOut and set annotationView objects to be accessible.
- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id )annotation { NSString *identifier = @"PINIDENTIFIER"; MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; if (annotationView == nil) { annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier]; annotationView.canShowCallout = true; UIButton *callOut = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; [callOut setAccessibilityValue:@"Tap To Perform Some Action"]; annotationView.rightCalloutAccessoryView = callOut; [annotationView setIsAccessibilityElement:YES]; annotationView.accessibilityValue = @"Tap this pin show a callout with more information."; } return annotationView; }
Make sure any UIView that the MKMapView may be contained in the XIB has it's accessibility option set to NO. Not doing so will cause the map view to be accessible, when it's only the pins and callouts that are desired.
An oldie, but interesting all the same. Ever wondered how MKMapView works? What exactly is the zoom level and how is it calculated? Read on.