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
Related
I have one view and one View Controller. I am trying to have a reference to View Controller from the view.
PlusCalendarView.h
#interface PlusCalendarView : TSQCalendarView
#property (nonatomic, strong) UIViewController *initialVC;
#end
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpCalendarView:self.myCalendarView];
self.myCalendarView.initialVC = self; // ERROR: Property initialVC not found on object of type "PlusCalendarView"
}
How come it cannot find initialVC property?
Update:
ViewController.h
#import <UIKit/UIKit.h>
#import <TimesSquare/TimesSquare.h>
#interface PlusCalendarView : TSQCalendarView;
#end
#interface ViewController : UIViewController
#property (nonatomic, strong) NSCalendar *calendar;
#property (strong, nonatomic) IBOutlet PlusCalendarView *myCalendarView;
#end
The problem is that you're declaring PlusCalendarView in ViewController.h AND PlusCalendarView.h. You should remove the #interface declaration from ViewController.h.
Instead, add #class PlusCalendarView in ViewController.h then #import "PlusCalendarView.h" in ViewController.m
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 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.
I'm trying to creating a custom UIView, lets call it FooView.
FooView.h
#import <UIKit/UIKit.h>
#interface FooView : UIView
#property (nonatomic, strong) UITextField *barTextField;
#property (nonatomic, strong) UIButton *submitButton;
#end
FooView.m
#import "FooView.h"
#implementation FooView
#synthesize barTextField = _barTextField;
#synthesize submitButton = _submitButton;
...
#end
FooViewController.h
#import <UIKit/UIKit.h>
#import "FooView.h"
#interface FooViewController : UIViewController
#property (nonatomic, strong) FooView *fooView;
#end
FooViewController.m
#import "SearchViewController.h"
#interface SearchViewController ()
#end
#implementation SearchViewController
#synthesize fooView = _fooView;
#end
I want the button touch event to be implemented in FooViewController, is delegate can achieve this? If YES, how?
Currently, I'm adding the touch event in such a way
FooViewController.m
- (void)viewDidLoad
{
[self.fooView.submitButton addTarget:self action:#selector(submitTapped:) forControlEvents:UIControlEventTouchUpInside];
}
...
- (IBAction)submitTapped
{
...
}
But I don't think this is a good solution, so need some expert advice.
Any idea?
Yes you can implement using delegate
FooView.h
#import <UIKit/UIKit.h>
#protocol FooViewDelegate
-(void)submitButtonClicked:(id)sender;
#end
#interface FooView : UIView
#property (nonatomic, strong) UITextField *barTextField;
#property (nonatomic, strong) UIButton *submitButton;
#property (nonatomic, assign) id<FooViewDelegate> delegate;
#end
FooView.m
#import "FooView.h"
#implementation FooView
#synthesize barTextField = _barTextField;
#synthesize submitButton = _submitButton;
#synthesize delegate;
...
-(IBAction)buttonClicked:(id)sender // connect this method with your button
{
[self.delegate submitButtonClicked:sender];
}
#end
FooViewController.h
#import <UIKit/UIKit.h>
#import "FooView.h"
#interface FooViewController : UIViewController <FooViewDelegate>
#property (nonatomic, strong) FooView *fooView;
#end
FooViewController.m
#import "FooViewController.h"
#interface FooViewController ()
#end
#implementation FooViewController
#synthesize fooView = _fooView;
- (void)viewDidLoad
{
_fooView = [[UIView alloc] init];
_fooView.delegate = self;
}
-(void)submitButtonClicked:(id)sender //delegate method implementation
{
NSLog(#"%#",[sender tag]);
}
#end
I was playing around with MKMap and some custom delegate it's not working here and i really don't know why :/
Here's my code :
LocationViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#protocol LocationViewDelegate <NSObject>
#required
- (void)didReceiveLocation:(CLLocation *)location;
#end
#interface LocationViewController : UIViewController <CLLocationManagerDelegate>
#property (strong, nonatomic) IBOutlet UILabel *locationLabel;
#property (nonatomic, strong) id<LocationViewDelegate> delegate;
- (IBAction)sendLocation:(id)sender;
#end
LocationViewController.m
[...]
- (IBAction)sendLocation:(id)sender {
if ([_delegate respondsToSelector:#selector(didReceiveLocation:)]) {
[_delegate didReceiveLocation:_currentLocation];
} else {
NSLog(#"nope");
}
}
[...]
MapViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "LocationViewController.h"
#interface MapViewController : UIViewController <LocationViewDelegate>
#end
MapViewController.m
[...]
- (void)didReceiveLocation:(CLLocation *)location {
_mapView.centerCoordinate = location.coordinate;
}
[...]
I'm always getting the "nope" message means that respondsToSelector returns NO.
I did pretty the same example a few days ago and everything was fine.
Someone can see where's the problem here ?
Set your MapViewController as the delegate for the LocationViewController i.e. in your MapViewController.m:
self.locationViewController.delegate = self;
Just as an aside, I'm presuming your MapViewController owns a LocationViewController instance, if so it's better to set the delegate property in LocationViewController to 'weak' to avoid a circular reference. #property (nonatomic, weak) id delegate;