Direction of target annotation when outside of visible area - ios

I would like to show the direction images on all sides of the screen. E.g. if the target's location is the right side of user's location and is outside of the visible map area, then I want to add a direction image as shown on the picture below (The Green annotation is user's location, red one is the direction for the target, which is out of bounds of the screen):
What is the standard approach to do this?

The simplest way is to place four "pointer" views above the map at each of the cardinal points. Then, as the user moves the map (using mapView:regionDidChangeAnimated: delegate method) determine which pointer should be shown. Hide all the other ones; and then show the correct one. Also, apply a transformation to the pointer so that the bearing angle is represented as you have done.
Here is a screenshot of a storyboard with the above configuration:
And here is a sample implementation (Code is not optimal, of course.):
//
// MapViewController.m
// AnimationTest
//
// Created by Scott Atkinson on 4/17/15.
//
#import "MapViewController.h"
#import MapKit;
typedef NS_ENUM(NSInteger, CardinalPoint) {
North,
South,
East,
West
};
#interface MapViewController () <MKMapViewDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
// Views that show cardinal points on the map (Only one should be shown at a time)
#property (weak, nonatomic) IBOutlet UIView *northPointerView;
#property (weak, nonatomic) IBOutlet UIView *eastPointerView;
#property (weak, nonatomic) IBOutlet UIView *westPointerView;
#property (weak, nonatomic) IBOutlet UIView *southPointerView;
// Location to show on the map
#property (strong, nonatomic) CLLocation * targetLocation;
#end
#implementation MapViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self hidePointerViews];
// Add the location to the map
self.targetLocation = [[CLLocation alloc] initWithLatitude:37.331898 longitude:-122.029824];
MKPlacemark * placemark = [[MKPlacemark alloc] initWithCoordinate:self.targetLocation.coordinate addressDictionary:nil];
[self.mapView addAnnotation:placemark];
}
// ******************** MKMapViewDelegate ********************
#pragma mark - MKMapViewDelegate
// As the map moves, update the cardinal pointer views
- (void) mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
if([self isCurrentLocationVisible] && ![self isTargetLocationVisible]) {
// The user location is visible, but the target is not, so show a pointer
double bearing = [self bearingToLocation:self.targetLocation fromLocation:self.mapView.userLocation.location];
[self showCardinalPointDirection:bearing];
} else {
// Hide the pointers
[self hidePointerViews];
}
}
// ******************** Coordinate Helpers ********************
#pragma mark - Coordinate Helpers
- (BOOL) isCurrentLocationVisible {
return MKMapRectContainsPoint(self.mapView.visibleMapRect,
MKMapPointForCoordinate(self.mapView.userLocation.coordinate));
}
- (BOOL) isTargetLocationVisible {
return MKMapRectContainsPoint(self.mapView.visibleMapRect,
MKMapPointForCoordinate(self.targetLocation.coordinate));
}
// From: http://stackoverflow.com/questions/3925942/cllocation-category-for-calculating-bearing-w-haversine-function
double DegreesToRadians(double degrees) {return degrees * M_PI / 180.0;};
double RadiansToDegrees(double radians) {return radians * 180.0/M_PI;};
/// Calculate the bearing between two points
-(double) bearingToLocation:(CLLocation *) destinationLocation fromLocation:(CLLocation *) fromLocation {
double lat1 = DegreesToRadians(fromLocation.coordinate.latitude);
double lon1 = DegreesToRadians(fromLocation.coordinate.longitude);
double lat2 = DegreesToRadians(destinationLocation.coordinate.latitude);
double lon2 = DegreesToRadians(destinationLocation.coordinate.longitude);
double dLon = lon2 - lon1;
double y = sin(dLon) * cos(lat2);
double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
double radiansBearing = atan2(y, x);
if(radiansBearing < 0.0)
radiansBearing += 2*M_PI;
return RadiansToDegrees(radiansBearing);
}
// ******************** Pointer View ********************
#pragma mark - Pointer View
- (void) hidePointerViews {
self.northPointerView.hidden =
self.southPointerView.hidden =
self.eastPointerView.hidden =
self.westPointerView.hidden = YES;
}
- (void) showCardinalPointDirection:(double) bearing {
CardinalPoint point = [self cardinalPointWithBearing:bearing];
// Determine which pointer should be shown based on the bearing
UIView * activePointer;
switch (point) {
case North:
activePointer = self.northPointerView;
break;
case South:
activePointer = self.southPointerView;
break;
case East:
activePointer = self.eastPointerView;
break;
case West:
activePointer = self.westPointerView;
break;
}
// Rotate the pointer to show the bearing
activePointer.transform = CGAffineTransformMakeRotation(DegreesToRadians(bearing));
// Hide all pointers except the pertinent one
[self hidePointerViews];
activePointer.hidden = NO;
}
/// Returns the cardinal point for a given bearing (in Degrees)
- (CardinalPoint) cardinalPointWithBearing:(double) bearing {
if (bearing > 45.0 && bearing <= 135.0) {
return East;
} else if (bearing > 135.0 && bearing <= 225.0) {
return South;
} else if (bearing > 225.0 && bearing <= 315.0) {
return West;
} else {
return North;
}
}
#end
Additionally, the pointer rotation is based on the bearing between the userLocation and the targetLocation. It feels a little strange. Probably better to make the rotation based off of some other point. Maybe the center of the visible region at that moment...

Related

The Pin is not working

My Map shows a pin on a specific place but it's not showing the pin
Here is the code
WadiRumViewControllerJordan.h
#import <UIKit/UIKit.h>
#include <MapKit/MapKit.h>
#interface WadiRumViewControllerJordan : UIViewController
#property (strong, nonatomic) IBOutlet MKMapView *WadiRumMapView;
#end
WadiRumViewControllerJordan.m
#import "WadiRumViewControllerJordan.h"
#import "WadiRumNSOjectPIN.h"
#interface WadiRumViewControllerJordan ()
#end
//Wadi Rum Coordinates
#define WadiRum_Latitude 29.537355
#define WidiRum_longtitude 35.415026
//Wadi Rum Span
#define WadiRumSpan 0.01f;
#implementation WadiRumViewControllerJordan
#synthesize WadiRumMapView;
- (void)viewDidLoad {
[super viewDidLoad];
//Create WadiRum Region
MKCoordinateRegion WadiRumRegion;
//Center
CLLocationCoordinate2D center;
center.latitude = WadiRum_Latitude;
center.longitude = WidiRum_longtitude;
//Span
MKCoordinateSpan span;
span.latitudeDelta = WadiRum_Latitude;
span.longitudeDelta = WidiRum_longtitude;
WadiRumRegion.center = center;
WadiRumRegion.span = span;
//Set our map
[WadiRumMapView setRegion:WadiRumRegion animated:YES];
//WadiRumNSObjectPIN
//1. Create a coordinate for the use of WadiRum
CLLocationCoordinate2D WadiRumLocation;
WadiRumLocation.latitude = WadiRum_Latitude;
WadiRumLocation.longitude = WidiRum_longtitude;
WadiRumNSOjectPIN * WadiRumAnnitation = [[WadiRumNSOjectPIN alloc] init];
WadiRumAnnitation.coordinate = WadiRumLocation;
WadiRumAnnitation.title = #"Services";
WadiRumAnnitation.subtitle = #"Desert";
{[self.WadiRumMapView addAnnotation:WadiRumAnnitation];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be WadiRumNSOjectPIN
}
#end
WadiRumNSOjectPIN.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface WadiRumNSOjectPIN : NSObject <MKAnnotation>
#property(nonatomic, assign) CLLocationCoordinate2D coordinate;
#property(nonatomic, copy) NSString * title;
#property(nonatomic, copy) NSString * subtitle;
#end
WadiRumNSOjectPIN.m
#import "WadiRumNSOjectPIN.h"
#implementation WadiRumNSOjectPIN
#synthesize coordinate;
- (id)initWithLocation:(CLLocationCoordinate2D)coord {
self = [super init];
if (self) {
coordinate = coord;
}
return self;
}
#synthesize coordinate, title, subtitle;
#end
I edited the code above to make it exactly like what I want, I got this error in the picture bellow
In order to conform to MKAnnotation, you must have properties called coordinate, title and subtitle. You've added three extra properties, ttcoordinate, tttitle, and ttsubtitle, but MKAnnotation is going to ignore those, and will look for coordinate, title, and subtitle.
The key reason you're not seeing your annotation is that you're setting ttcoordinate in viewDidLoad. But MKAnnotation will not use that, but rather will refer to the coordinate property you synthesized, but never set. (You do have an initWithLocation method, which suggests you were going to update coordinate, but you never call that.)
Bottom line, I would suggest renaming ttcoordinate, ttitle and ttsubtitle to coordinate, title, and subtitle, and updating all of those references accordingly, and that should fix everything. And you can retire the #synthesize line.

UIImageView not responding to centering

I'm trying to put together a simple compass for iOS. The rotation animation seems to rotate the compass image around the center of the screen so I am trying to automatically center the UIImageView of compass Image so that it will work on different devices.
And this is where my problem is. I have attempted to center the image with the following code within ViewDidLoad but with no result:
compassImage.center = CGPointMake(CGRectGetMidX(self.view.frame), CGRectGetMidY(self.view.frame));
I have originally placed the compass image in a random place within the Storyboard just to make sure this works. I have printed NSLog checks before and after this centering code to make sure that it is having and effect and it does seem to be centering the image (on my iPhone 4s) yet this is not reflected in the view:
2014-05-17 12:18:23.015 Compass[447:60b] Old: 160, 386
2014-05-17 12:18:23.019 Compass[447:60b] New: 160, 240
I'd post an image but am not allowed as it is my first post.
In fact heres the whole setup. I'm sure I've gone wrong somewhere:
ViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <QuartzCore/QuartzCore.h>
#interface ViewController : UIViewController <CLLocationManagerDelegate>
#property (nonatomic, retain) CLLocationManager *locationManager;
#property (nonatomic, retain) IBOutlet UIImageView *compassImage;
#property (nonatomic, retain) IBOutlet UILabel *trueHeadingLabel;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController()
#end
#implementation ViewController
#synthesize locationManager, compassImage, trueHeadingLabel;
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"Old: %i, %i", (int)compassImage.center.x, (int)compassImage.center.y);
compassImage.center = CGPointMake(CGRectGetMidX(self.view.frame), CGRectGetMidY(self.view.frame));
NSLog(#"New: %i, %i", (int)compassImage.center.x, (int)compassImage.center.y);
locationManager=[[CLLocationManager alloc] init];
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.headingFilter = 1;
locationManager.delegate=self;
// Start the compass updates
[locationManager startUpdatingHeading];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
// Convert Degree to Radian
// Multiply by -1 to twist opposite to phone rotation
float oldRad = -manager.heading.trueHeading * M_PI / 180.0f;
float newRad = -newHeading.trueHeading * M_PI / 180.0f;
// creating needle spin animation
CABasicAnimation *theAnimation;
theAnimation=[CABasicAnimation animationWithKeyPath:#"transform.rotation"];
theAnimation.fromValue = [NSNumber numberWithFloat:oldRad];
theAnimation.toValue=[NSNumber numberWithFloat:newRad];
theAnimation.duration = 0.5f;
// applying the animation
[compassImage.layer addAnimation:theAnimation forKey:#"animateMyRotation"];
compassImage.transform = CGAffineTransformMakeRotation(newRad);
// setting labels to heading
trueHeadingLabel.text = [NSString stringWithFormat:#"%i°", (int)(newHeading.trueHeading)];
// console print of heading
NSLog(#"True heading: %f", newHeading.trueHeading);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I have looked at pretty much every question and answer on here with anything to do with changing the position of a UIImageView and centering and nothing is doing the job. I get the feeling that it could just be the way I'm setting up the whole program and this wouldn't be a surprise since I am a new and super-inexperienced. Any help would be fantastic. Even advice on better programming practice too. If you need any more information gimmie a shout.
Sounds like you may have autolayout enabled and that overrides your code.
Change:
compassImage.center = CGPointMake(CGRectGetMidX(self.view.frame), CGRectGetMidY(self.view.frame));
To:
compassImage.center = self.view.center;
Also, make sure that you have no constraints on the compassImage in IB that would interfere.

How to call a variable from another class

First off, do you guys know of any good tutorial sites or books to learn how to code for iOS6?
Now to the problem at hand, I have an AppDelegate class and a ViewController class.
I am using the AppDelegate class to find my current location and save it as an NSString.
I have a label in my ViewController class where I want to display my location.
In java I would usually just do something like this
label.text = AppDelegate.myLocationString;
But I am fairly new to objective c and I don't know how to do the equivalent. To be honest I'm not even sure if I am taking the correct approach for this language. Is there another way to approach this problem in objective c?
I've tried searching around for how to do it but I'm not even sure that I'm phrasing my searches correctly so I don't know if I'm searching in the right direction.
Any help that could be offered would be very much appreciated
My code as it is now:
AppDelegate.h
#import <UIKit/UIKit.h>
#import CoreLocation/CoreLocation.h
#class BIDViewController;
#interface BIDAppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) BIDViewController *viewController;
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (strong, nonatomic) NSString *myPosition;
#end
LocationManager class from AppDelegate.m
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSDate *eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 15) {
//if it is within the last 15 seconds, use it. Else do nothing.
if (newLocation.horizontalAccuracy < 35.0) {
//location seems pretty accurate so we will use it
NSLog(#"latitude: %+.6f, longitude: %+.6f\n", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
NSLog(#"Horizontal accuracy: %f", newLocation.horizontalAccuracy);
int latDegrees = newLocation.coordinate.latitude;
int lonDegrees = newLocation.coordinate.longitude;
double latDecimal = fabs(newLocation.coordinate.latitude - latDegrees);
double lonDecimal = fabs(newLocation.coordinate.longitude - lonDegrees);
int latMinutes = latDecimal * 60;
int lonMinutes = lonDecimal * 60;
double latSeconds = ((latDecimal * 3600) - (latMinutes * 60));
double lonSeconds = ((lonDecimal * 3600) - (lonMinutes * 60));
_myPosition = [NSString stringWithFormat:#"Lat: %d, %d, %1.4f, Lon: %d, %d, %1.4f", latDegrees, latMinutes, latSeconds, lonDegrees, lonMinutes, lonSeconds];
}
}
}
ViewController.h
#import <UIKit/UIKit.h>
#interface BIDViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *positionLabel;
#end
ViewController.m
#import "BIDViewController.h"
#import "BIDAppDelegate.h"
#interface BIDViewController ()
#end
#implementation BIDViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//I have tried setting the label's text here but to no avail so far, I have been
//able to set it as "blah" with the following line:
//
// positionLabel.text = #"blah";
//
//and I have tried things such as the following to populate the label with the
//myPosition variable:
//
// positionLabel.text = _myPosition;
// or
// positionLabel.text = AppDelegate._myPosition;
}
- (void)viewDidUnload
{
[self setPositionLabel:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
To reference the App Delegate from your view controller, first import its definition (which you've ready done):
#import "BIDAppDelegate.h"
and then in code get the delegate:
BIDAppDelegate *appDelegate = (BIDAppDelegate *)[[UIApplication sharedApplication] delegate];
and then get the location from the delegate:
CLLocation *location = appDelegate.locationManager.location;
and then call whatever method you like on the location object:
NSString *descr = location.description;
Or get the pre-calculated position with:
NSString *position = appDelegate.myPosition;
In your ViewController
BIDAppDelegate *appDelegate = (BIDAppDelegate *)[UIApplication sharedApplication].delegate;
[positionLabel setText:appDelegate.myPosition];
How to call a variable from another class?
Assume you are in ClassB
ClassA *aObj=... ; //create an object of ClassA
aObj.propertyName=...;//set the property or ivar
NSString *string=aObj.propertyName;//retrieve it
do you guys know of any good tutorial sites or books to learn how to
code for iOS6?
http://www.lynda.com/Apple-training-tutorials/106-0.html
http://www.raywenderlich.com/tutorials

UISlider moving UIImage

I am using a UIslider to move a UIImage left and right on the screen. When the UISlider is totally on the left the image will be to a certain position on the X atis on the left of the screen, and when the slider is totally to the right, the image is on the right of the screen. If for example I want to give the image flexibility movement of 600px, how can I do that?
-(IBAction)sliderValueChanged:(UISlider *)sender
{
if (sender.value >= 0.5) {
int value;
value = sender.value * 6;
[photoView setFrame:CGRectMake(photoView.frame.origin.x + value,
PhotoView.frame.origin.y,photoView.frame.size.width,photoView.frame.size.height)];
}else{
int value;
value = sender.value * -6;
[photoView setFrame:CGRectMake(photoView.frame.origin.x + value,
photoView.frame.origin.y,photoView.frame.size.width,photoView.frame.size.height)];
}
...this was my guess
I recently had to do the same thing you're trying to do for use in a full scale aircraft where the iPad/iPhone acts as a instrument gauge.
Here is the code I used to move an image for the aircraft's instrument readout: Also, you should round the float value to an int because we are dealing with whole pixel points. (The image will still move fine with a float value, but I like using an int when dealing with pixel points.)
#import "ViewController.h"
#import <math.h>
#interface ViewController()
#property (nonatomic, strong) IBOutlet UIImageView *XAxis;
#property (nonatomic, strong) IBOutlet UISlider *XSlider;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.XSlider.minimumValue = 0.0f;
self.XSlider.maximumValue = 600.0f;
}
- (IBAction)XValueChanged:(UISlider *)XSlider;
{
int XResult = (int)floorf(XSlider.value);
self.XAxis.center = CGPointMake(self.XAxis.center.x, XResult);
NSLog(#"X Value: %d", XResult);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
How about something like this,
slider.minimumValue = 0.0f;
slider.maximumValue = 600.0f;
-(IBAction)sliderValueChanged:(UISlider *)sender
{
[photoView setFrame:CGRectMake(sender.value, PhotoView.frame.origin.y,photoView.frame.size.width,photoView.frame.size.height)];
}
You can also do this by changing photoView.frame.origin.x + value to floatValue + value where floatValue is some fixed number based on where you want to set the photoView. Also calculate value as value = sender.value * constant where constant again depends on how much you need to move it for each slider movement.
Check documentation for more details on properties

IOS 4.3.2 MapKit Annotations

Hello we have an app that we are working on that is having some issuse getting the annotations to function correctly. The app builds and installs fine... there are about 50k pins being loaded from a database on the ipad...
The problem is that every pin will display the same annotation information when pressed... can't figure out how to have it reference the correct database field when a pin is pressed (the pins are all being displayed in the correct locations so we know it is referencing the database)
I imagine it's something here?
- (void) loadThePushPinInMap {
NSString * filename= [[NSBundle mainBundle] pathForResource:#"geocoded" ofType:#"csv"];
NSString *data = [NSString stringWithContentsOfFile:filename];
NSString *strippedPartOne = [data stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSArray *rows = [strippedPartOne componentsSeparatedByString:#"\r"];
int size = [rows count];
for (int i =0; i < size; i++) {
if(i==0)
continue;
// This is now the data being parse
NSArray * line = [[rows objectAtIndex:i] componentsSeparatedByString:#","];
double lat =[[[line objectAtIndex:5] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] doubleValue];
double lon =[[[line objectAtIndex:6] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] doubleValue];
//MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
//region.center.latitude = lat ;
//region.center.longitude = lon;
//region.span.longitudeDelta = 0.01f;
//region.span.latitudeDelta = 0.01f;
CLLocationCoordinate2D coordinate;
coordinate.latitude = lat;
coordinate.longitude = lon;
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = coordinate;
annotation.title = [rows objectAtIndex:0];
annotation.subtitle = [rows objectAtIndex:4];
//[_mapView addAnnotation:annotation];
[self.mapView addAnnotation:annotation];
}
}
Here is the MKAnnotationsview code
#import <UIKit/UIKit.h>
#import <MapKit/MKFoundation.h>
// Post this notification to re-query callout information.
MK_EXTERN NSString * const MKAnnotationCalloutInfoDidChangeNotification;
#if (__IPHONE_4_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED)
enum {
MKAnnotationViewDragStateNone = 0, // View is at rest, sitting on the map.
MKAnnotationViewDragStateStarting, // View is beginning to drag (e.g. pin lift)
MKAnnotationViewDragStateDragging, // View is dragging ("lift" animations are complete)
MKAnnotationViewDragStateCanceling, // View was not dragged and should return to it's starting position (e.g. pin drop)
MKAnnotationViewDragStateEnding // View was dragged, new coordinate is set and view should return to resting position (e.g. pin drop)
};
typedef NSUInteger MKAnnotationViewDragState;
#endif // #if (__IPHONE_4_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED)
#class MKAnnotationViewInternal;
#protocol MKAnnotation;
MK_CLASS_AVAILABLE(NA, 3_0)
#interface MKAnnotationView : UIView
{
#private
MKAnnotationViewInternal *_internal;
}
- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier;
#property (nonatomic, readonly) NSString *reuseIdentifier;
// Classes that override must call super.
- (void)prepareForReuse;
#property (nonatomic, retain) id <MKAnnotation> annotation;
#property (nonatomic, retain) UIImage *image;
// By default, the center of annotation view is placed over the coordinate of the annotation.
// centerOffset is the offset in screen points from the center of the annotion view.
#property (nonatomic) CGPoint centerOffset;
// calloutOffset is the offset in screen points from the top-middle of the annotation view, where the anchor of the callout should be shown.
#property (nonatomic) CGPoint calloutOffset;
// Defaults to YES. If NO, ignores touch events and subclasses may draw differently.
#property (nonatomic, getter=isEnabled) BOOL enabled;
// Defaults to NO. This gets set/cleared automatically when touch enters/exits during tracking and cleared on up.
#property (nonatomic, getter=isHighlighted) BOOL highlighted;
// Defaults to NO. Becomes YES when tapped on in the map view.
#property (nonatomic, getter=isSelected) BOOL selected;
- (void)setSelected:(BOOL)selected animated:(BOOL)animated;
// If YES, a standard callout bubble will be shown when the annotation is selected.
// The annotation must have a title for the callout to be shown.
#property (nonatomic) BOOL canShowCallout;
// The left accessory view to be used in the standard callout.
#property (retain, nonatomic) UIView *leftCalloutAccessoryView;
// The right accessory view to be used in the standard callout.
#property (retain, nonatomic) UIView *rightCalloutAccessoryView;
// If YES and the underlying id<MKAnnotation> responds to setCoordinate:,
// the user will be able to drag this annotation view around the map.
#property (nonatomic, getter=isDraggable) BOOL draggable NS_AVAILABLE(NA, 4_0);
// Automatically set to MKAnnotationViewDragStateStarting, Canceling, and Ending when necessary.
// Implementer is responsible for transitioning to Dragging and None states as appropriate.
#property (nonatomic) MKAnnotationViewDragState dragState NS_AVAILABLE(NA, 4_0);
// Developers targeting iOS 4.2 and after must use setDragState:animated: instead of setDragState:.
- (void)setDragState:(MKAnnotationViewDragState)newDragState animated:(BOOL)animated NS_AVAILABLE(NA, 4_2);
#end
Here is the Delegate.h codes.....
#import "MapinAppDelegate.h"
#implementation MapinAppDelegate
#synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
*/
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
/*
Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
*/
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
}
- (void)applicationWillTerminate:(UIApplication *)application
{
/*
Called when the application is about to terminate.
Save data if appropriate.
See also applicationDidEnterBackground:.
*/
}
#end
Here are the Delegate.m codes....
#import <UIKit/UIKit.h>
#interface MapinAppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#end
Use CustomAnnotaion which is inherited by MKAnnotation only, in that class assign your own properties, like locationDetails, locationImage, etc.
To add this information, update your MKAnnotatinView, by implementing this delegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation
Example:
http://developer.apple.com/library/ios/#DOCUMENTATION/UserExperience/Conceptual/LocationAwarenessPG/AnnotatingMaps/AnnotatingMaps.html
http://www.highoncoding.com/Articles/805_Consuming_XML_Feed_and_Displaying_Public_Information_on_the_MapView_Control.aspx

Resources