I'm trying to simple alter the image of a pin on the map, but I can't create the annotation due this error.
Theres my "PlaceMark.h":
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface PlaceMark : NSObject <MKAnnotation>
#property (nonatomic, readonly) CLLocationCoordinate2D coordenada;
#property (copy, nonatomic) NSString *titulo;
-(id)initWithTitle:(NSString *)novoTitulo Location:(CLLocationCoordinate2D)location;
-(MKAnnotationView *)annotationView;
#end
My "PlaceMark.m":
#import "PlaceMark.h"
#implementation PlaceMark
#synthesize coordenada;
#synthesize titulo;
-(id)initWithTitle:(NSString *)novoTitulo Location:(CLLocationCoordinate2D)location{
self=[super init];
if(self){
titulo=novoTitulo;
coordenada=location;
}
return self;
}
-(MKAnnotationView *)annotationView{
MKAnnotationView *annotationView=[[MKAnnotationView alloc] initWithAnnotation:self reuseIdentifier:#"ponto"];
annotationView.enabled=true;
annotationView.canShowCallout=true;
annotationView.image=[UIImage imageNamed:#"placa.png"];
return annotationView;
}
#end
Edit:
Heres where I am instantiating the marker:
//heres the error
PlaceMark *ponto = [[PlaceMark alloc] initWithTitle:#"Ponto" Location:coordinate];
[_mapKit addAnnotation:ponto];
Already tried cleaning and Rebuild
What's wrong?
Thanks :)
Related
I am getting Use of undeclared identifier 'AIRGoogleMapOverlay' error when I am trying to run my react native project through Xcode. I am actually trying to open the app on my iPhone and thats when I encounter this error. If I simply say react-native run-ios, it builds and launches the app on simulator. I am trying to extract current device location which I can't do using a simulator.
The error occurs in the AirGoogleMapOverlayManager.m file which exists in the react-native-google-maps package.
AIRGoogleMapOverlay.h
#ifdef HAVE_GOOGLE_MAPS
#import <Foundation/Foundation.h>
#import <GoogleMaps/GoogleMaps.h>
#import <React/RCTBridge.h>
#import "AIRMapCoordinate.h"
#import "AIRGoogleMap.h"
#interface AIRGoogleMapOverlay : UIView
#property (nonatomic, strong) GMSGroundOverlay *overlay;
#property (nonatomic, copy) NSString *imageSrc;
#property (nonatomic, strong, readonly) UIImage *overlayImage;
#property (nonatomic, copy) NSArray *boundsRect;
#property (nonatomic, readonly) GMSCoordinateBounds *overlayBounds;
#property (nonatomic, weak) RCTBridge *bridge;
#end
#endif
AIRGoogleMapOverlay.m
#ifdef HAVE_GOOGLE_MAPS
#import "AIRGoogleMapOverlay.h"
#import <React/RCTEventDispatcher.h>
#import <React/RCTImageLoader.h>
#import <React/RCTUtils.h>
#import <React/UIView+React.h>
#interface AIRGoogleMapOverlay()
#property (nonatomic, strong, readwrite) UIImage *overlayImage;
#property (nonatomic, readwrite) GMSCoordinateBounds *overlayBounds;
#end
#implementation AIRGoogleMapOverlay {
RCTImageLoaderCancellationBlock _reloadImageCancellationBlock;
CLLocationCoordinate2D _southWest;
CLLocationCoordinate2D _northEast;
}
- (instancetype)init
{
if ((self = [super init])) {
_overlay = [[GMSGroundOverlay alloc] init];
}
return self;
}
- (void)setImageSrc:(NSString *)imageSrc
{
NSLog(#">>> SET IMAGESRC: %#", imageSrc);
_imageSrc = imageSrc;
if (_reloadImageCancellationBlock) {
_reloadImageCancellationBlock();
_reloadImageCancellationBlock = nil;
}
__weak typeof(self) weakSelf = self;
_reloadImageCancellationBlock = [_bridge.imageLoader loadImageWithURLRequest:[RCTConvert NSURLRequest:_imageSrc]
size:weakSelf.bounds.size
scale:RCTScreenScale()
clipped:YES
resizeMode:RCTResizeModeCenter
progressBlock:nil
partialLoadBlock:nil
completionBlock:^(NSError *error, UIImage *image) {
if (error) {
NSLog(#"%#", error);
}
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#">>> IMAGE: %#", image);
weakSelf.overlayImage = image;
weakSelf.overlay.icon = image;
});
}];
}
- (void)setBoundsRect:(NSArray *)boundsRect
{
_boundsRect = boundsRect;
_southWest = CLLocationCoordinate2DMake([boundsRect[1][0] doubleValue], [boundsRect[0][1] doubleValue]);
_northEast = CLLocationCoordinate2DMake([boundsRect[0][0] doubleValue], [boundsRect[1][1] doubleValue]);
_overlayBounds = [[GMSCoordinateBounds alloc] initWithCoordinate:_southWest
coordinate:_northEast];
_overlay.bounds = _overlayBounds;
}
#end
#endif
And here is where I get the error, in AIRGoogleMapOverlayManager
#import "AIRGoogleMapOverlayManager.h"
#import "AIRGoogleMapOverlay.h"
#interface AIRGoogleMapOverlayManager()
#end
#implementation AIRGoogleMapOverlayManager
- (UIView *)view
{
AIRGoogleMapOverlay *overlay = [AIRGoogleMapOverlay new]; ERROR-Use of undeclared identifier 'AIRGoogleMApOverlay'
overlay.bridge = self.bridge; ERROR-Use of undeclared identifier 'overlay'
return overlay; ERROR-Use of undeclared identifier 'overlay'
return 0;
}
RCT_EXPORT_MODULE()
RCT_REMAP_VIEW_PROPERTY(bounds, boundsRect, NSArray)
RCT_REMAP_VIEW_PROPERTY(image, imageSrc, NSString)
#end
I know that solving the first will get rid of all 3 errors. Also I am running xcworkspace, not xcodeproj.
Any help is appreciated!
I added HAVE_GOOGLE_MAPS=1 to the preprocessor macros, all the AIRGoogleMapOverlay related errors were gone.
This needs to be added for both Debug and Release in case someone is wondering why they are getting this error while trying to create an offline bundle.
You might need a bridging header.
Create a file in your project, named for instance AIRGoogleMapOverlay-Bridging-Header.h
and put
#import "AIRGoogleMapOverlay.h"
in it.
Finally, add the header file in your Build settings like below, depending on the environment you need it to be set up.
I have the singleton class that stores the property - selected location (MKPointAnnotation). This location is set from the first map view by the user. However, I don't grasp why this property is null? Here the code.
Link to the project
The selected pieces of the code.
Class where I store information about the selected place:
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface GeoChatInformationAboutTheSelectedPlace : NSObject <MKMapViewDelegate>
//create object that mimic the Place with the required information
#property (nonatomic) NSUInteger numberOfThePostsForTheSelectedLocation;
#property (nonatomic, strong) MKPointAnnotation *annotation;
+(GeoChatInformationAboutTheSelectedPlace *)returnInstance;
#end
//implementation of the above class
#import "GeoChatInformationAboutTheSelectedPlace.h"
#implementation GeoChatInformationAboutTheSelectedPlace
static GeoChatInformationAboutTheSelectedPlace *info=NULL;
+(GeoChatInformationAboutTheSelectedPlace *)returnInstance{
if (!info){
info = [[GeoChatInformationAboutTheSelectedPlace alloc] init];
info.annotation=[[MKPointAnnotation alloc] init];
}
return info;
}
#end
How I add the selected location (based on Anna's comments):
.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "GeoChatInformationAboutTheSelectedPlace.h"
#interface GeoChatMapViewController : UIViewController <MKMapViewDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *map;
#property (strong,nonatomic) NSMutableArray *matchingItems;
#property (strong, nonatomic) IBOutlet UITextField *textSearch;
#property (strong, nonatomic) GeoChatInformationAboutTheSelectedPlace *info;
#property (weak, nonatomic) IBOutlet UIStepper *stepper;
- (IBAction)increaseDecreaseRadiousOfTheSearch:(id)sender;
#end
/*------------part of the implementation class--------*/
//selecting the location and displaying its coordinates
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Would you like to add this location?"
message:[view.annotation title]
delegate:self
cancelButtonTitle:#"Yep!"
otherButtonTitles:#"No :(", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex==0) {
MKAnnotationView *selectedAnnotation=[_map.selectedAnnotations objectAtIndex:0];
if ([selectedAnnotation isKindOfClass:[MKPointAnnotation class]]) {
MKPointAnnotation *pa = (MKPointAnnotation *)selectedAnnotation;
//[_info.arrayOfTheSelectedPlaces addObject:pa];
_info.annotation=pa;
}
}
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_info=[GeoChatInformationAboutTheSelectedPlace returnInstance];
_map.showsUserLocation=YES;
}
How I display the selected annotation at the second map:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "GeoChatInformationAboutTheSelectedPlace.h"
#interface GeoChatProjectSavedLocationToDisplayOnMapViewController : UIViewController <MKMapViewDelegate>
#property (strong, nonatomic) IBOutlet MKMapView *map;
#property (strong, nonatomic) GeoChatInformationAboutTheSelectedPlace *info;
#property (strong, nonatomic) MKPointAnnotation *bb;
#end
/*----------------------------.m---------------------------------------*/
#import "GeoChatProjectSavedLocationToDisplayOnMapViewController.h"
#interface GeoChatProjectSavedLocationToDisplayOnMapViewController ()
#end
#implementation GeoChatProjectSavedLocationToDisplayOnMapViewController
-(void)setBb:(MKPointAnnotation *)bb{
_bb=bb;
}
-(void)setMap:(MKMapView *)map {
_map=map;
_map.delegate=self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_map.showsUserLocation=YES;
_info=[GeoChatInformationAboutTheSelectedPlace returnInstance];
//displays nothing
NSLog(#"%#",[_info.annotation title]);
//however, when I write
//NSLog(#"%#",_info.annotation);
//It displays me that the object is not nill
//adds nothing to the map
[_map addAnnotation:_info.annotation];
}
#end
I have a problem obtaining the value of a NSString, named latitudeString from another class. Currently I have two view controllers, the first has users coordinates and the second has a MKMapView which show the current user position on a map. The problem is that I want the pin to show the coordinates of the user position in his subtitle but I can't obtain the value of latitudeString and Xcode gives me this error:
Property 'latitudeString' not found on object of type 'ViewController *'
Here's the code:
ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController <CLLocationManagerDelegate>
{
}
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
{
CLLocation *newLocation;
NSString *latitudeString;
}
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (strong, nonatomic) NSString *latitudeString;
#end
#implementation ViewController
#synthesize latitudeString;
CLLocationManager *locationManager;
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
newLocation = [locations lastObject];
latitudeString = [NSString stringWithFormat:#"%g\u00B0", newLocation.coordinate.latitude];
}
#end
MapViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface MapViewController : UIViewController <MKMapViewDelegate>
{
}
#end
MapViewController.m
#import "MapViewController.h"
#import "ViewController.h"
#interface MapViewController ()
{
ViewController *firstViewController;
}
#property (strong, nonatomic) ViewController *firstViewController;
#property (strong, nonatomic) IBOutlet MKMapView *mapView;
#end
#implementation MapViewController
#synthesize firstViewController;
- (void)viewDidLoad
{
self.mapView.showsUserLocation = YES;
self.mapView.delegate = self;
self.mapView.userLocation.title = #"Posizione attuale";
self.mapView.userLocation.subtitle = [NSString stringWithFormat:#"%#", firstViewController.latitudeString]; // ERROR
[super viewDidLoad];
}
#end
Can someone help me with this problem? Thanks.
Update #1
ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController <CLLocationManagerDelegate>
{
CLLocation *newLocation;
NSString *latitudeString;
}
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
{
}
#property (strong, nonatomic) CLLocationManager *locationManager;
#end
#implementation ViewController
CLLocationManager *locationManager;
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
newLocation = [locations lastObject];
self->latitudeString = [NSString stringWithFormat:#"%g\u00B0", newLocation.coordinate.latitude];
}
#end
MapViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface MapViewController : UIViewController <MKMapViewDelegate>
{
ViewController *firstViewController;
}
#property (strong, nonatomic) ViewController *firstViewController;
#property (strong, nonatomic) IBOutlet MKMapView *mapView;
#end
MapViewController.m
#import "MapViewController.h"
#import "ViewController.h"
#interface MapViewController ()
{
}
#end
#implementation MapViewController
- (void)viewDidLoad
{
self.mapView.showsUserLocation = YES;
self.mapView.delegate = self;
self.mapView.userLocation.title = #"Posizione attuale";
self.mapView.userLocation.subtitle = [NSString stringWithFormat:#"%#", firstViewController->latitudeString]; // ERROR
[super viewDidLoad];
}
#end
The latitudeString property of ViewController is a private property. Only methods of ViewController can access it. If you want it to be a public property you need to move the property declaration to the .h file.
BTW - get rid of all of your calls to #synthesize. As used, they are obsolete. Also get rid of the ivars you defined for the properties. They are also obsolete.
Try this:
ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController <CLLocationManagerDelegate>
// A public property
#property (strong, nonatomic) NSString *latitudeString;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
// A private property
#property (strong, nonatomic) CLLocationManager *locationManager;
#end
#implementation ViewController {
// A private instance variable (ivar)
CLLocation *newLocation;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
newLocation = [locations lastObject];
self.latitudeString = [NSString stringWithFormat:#"%g\u00B0", newLocation.coordinate.latitude];
}
#end
I am doing some unit tests on a ViewController that has an MKMapView.
If I want to test if the mapview is not nil, I have to explicitly initialize it, which is unnecessary to otherwise just use the mapview.
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface HomeVC : UIViewController <UIImagePickerControllerDelegate, CLLocationManagerDelegate, MKMapViewDelegate> {
MKMapView* mapView;
CLLocationManager* locationManager;
CLLocationCoordinate2D currentLocation;
}
#property (nonatomic, strong) IBOutlet MKMapView* mapView;
#property(nonatomic, strong)CLLocationManager* locationManager;
#property(nonatomic)CLLocationCoordinate2D currentLocation;
#end
#implementation HomeVC
#synthesize mapView, cameraButton,cameraView, locationManager, currentLocation;
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView = MKMapView.new;
self.mapView.mapType = MKMapTypeStandard;
}
If I put a breakpoint after the map initialization, it shows the mapView initialized with only a UIView property. It is properly hooked up in my Storyboard file. And works fine, I just can't test any properties on it.
An instance 0x11d0ce4b0 of class -(MyAnnotation annotation) was
deallocated while key value observers were still registered with it.
Observation info was leaked, and may even become mistakenly attached
to some other object. Set a breakpoint on NSKVODeallocateBreak to stop
here in the debugger. Here's the current observation info:
But I have put a breakpoint on my dealloc method, and in there, I do deregister for those notifications. Dealloc is called, and I did check that it was the same object, and all the calls to deregister are there. So I don't know how it could not be removing the observers.
Create custom AnnotationView:
#import <MapKit/MapKit.h>
#interface AnnotationView : MKPlacemark
#property (nonatomic, readwrite, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, strong) NSString *title;
#property (nonatomic, strong) NSString *subtitle;
#end
And in .m file
#import "AnnotationView.h"
#implementation AnnotationView
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate addressDictionary:(NSDictionary *)addressDictionary
{
if ((self = [super initWithCoordinate:coordinate addressDictionary:addressDictionary]))
{
self.coordinate = coordinate;
}
return self;
}
#end
// Use Annotation Add #import "AnnotationView.h" in your relevant .m file:
CLLocationCoordinate2D pCoordinate ;
pCoordinate.latitude = LatValue;
pCoordinate.longitude = LanValue;
// Create Obj Of AnnotationView class
AnnotationView *annotation = [[AnnotationView alloc] initWithCoordinate:pCoordinate addressDictionary:nil] ;
annotation.title = #"I m Here";
annotation.subtitle = #"This is Sub Tiitle";
[self.mapView addAnnotation:annotation];
Above is simple Example of how to create AnnotationView.