Daniel Fernandez Daniel Fernandez - 13 days ago 6
iOS Question

Passing data using calloutAccessoryControlTapped Xcode

I am developing an app in Xcode (objective-c). My app has a TableView with a list of restaurants and when you press one row, another view is opened with the restaurant information. The method I am using is that I am sending the title in the row to the new view and depending on the title I load the information of the restaurant. I want to do exactly the same using a map pin button. My problem is that I am trying to send the

TitleLabel
to other ViewController but this is not working and I don't know why.

This is my map pin: RestMapPin.h:

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface RestMapPin : NSObject <MKAnnotation> {

CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subtitle;
}

@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;

@end


This is my RestMappin.m:

#import "RestMapPin.h"

@implementation RestMapPin

@synthesize coordinate, title, subtitle;

@end


This is my MapViewController.h:

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>

@interface MapViewController : UIViewController {

MKMapView *mapView;
}

@property (weak, nonatomic) IBOutlet UIBarButtonItem *barButton;

@property (nonatomic, retain) IBOutlet MKMapView *mapView;

-(IBAction)setMap:(id)sender;

@end


This is my MapViewController.m:

#import "MapViewController.h"
#import "SWRevealViewController.h"
#import "RestMapPin.h"
#import "RestViewController.h"
#import "MainTableViewController.h"

@interface MapViewController ()

@end

@implementation MapViewController

@synthesize mapView;

- (void)viewDidLoad {
[super viewDidLoad];

_barButton.target = self.revealViewController;
_barButton.action = @selector(revealToggle:);

[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];

mapView.delegate = self;

/*Babelia*/
MKCoordinateRegion region_Babelia = { {0.0, 0.0}, {0.0, 0.0}};
region_Babelia.center.latitude = 40.4234778;
region_Babelia.center.longitude = -3.686283000000003;
region_Babelia.span.longitudeDelta = 0.1f;
region_Babelia.span.latitudeDelta = 0.1f;
[mapView setRegion:region_Babelia animated:YES];

RestMapPin *ann_Babelia = [[RestMapPin alloc] init];
ann_Babelia.title = @"Babelia";
ann_Babelia.subtitle = @"Barrio de Salamanca";
ann_Babelia.coordinate = region_Babelia.center;
[mapView addAnnotation:ann_Babelia];

/*Bacira*/
MKCoordinateRegion region_Bacira = { {0.0, 0.0}, {0.0, 0.0}};
region_Bacira.center.latitude = 40.43375390000001;
region_Bacira.center.longitude = -3.699036299999989;
region_Bacira.span.longitudeDelta = 0.1f;
region_Bacira.span.latitudeDelta = 0.1f;
[mapView setRegion:region_Bacira animated:YES];

RestMapPin *ann_Bacira = [[RestMapPin alloc] init];
ann_Bacira.title = @"Bacira";
ann_Bacira.subtitle = @"Chamberí";
ann_Bacira.coordinate = region_Bacira.center;
[mapView addAnnotation:ann_Bacira];

/*Indicador de posicion del mapa (para centrarlo)*/
MKCoordinateRegion region_posicion = { {0.0, 0.0}, {0.0, 0.0}};
region_posicion.center.latitude = 40.44934744420573;
region_posicion.center.longitude = -3.695504665374756;
region_posicion.span.longitudeDelta = 0.08f;
region_posicion.span.latitudeDelta = 0.08f;
[mapView setRegion:region_posicion animated:YES];
/*************************************************/
}

-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{
MKAnnotationView *pinView = nil;
if(annotation != mapView.userLocation) {
static NSString *defaultPinID = @"com.invasivecode.pin";
pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
pinView = [[MKAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:defaultPinID];


pinView.canShowCallout = YES;
pinView.image = [UIImage imageNamed:@"pin2@2x.png"];
}
else {
//[mapView.userLocation setTitle:@"I am here"];
}


UIButton *pinButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
//if ([[annotation title] isEqualToString:@"Marieta"]) {
//[pinButton addTarget:self action:@selector(annotationView:) forControlEvents:UIControlEventTouchUpInside];
//}
pinView.rightCalloutAccessoryView = pinButton;


return pinView;
}


- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
RestMapPin *selectedAnnotation = view.annotation;
NSLog(@"Title of selected pin - %@", selectedAnnotation.title);
// Here you get the title of selected annotation

//RestViewController *objYourVC = [[RestViewController alloc]init];
RestViewController *objYourVC = [self.storyboard instantiateViewControllerWithIdentifier:@"MyIdentifier"];


objYourVC.TitleLabel = selectedAnnotation. title;
NSLog(@"objYourVC.TitleLabel - %@", objYourVC.TitleLabel);
//objYourVC.DetailModal.title = selectedAnnotation.title;
//NSLog(@"objYourVC.TitleLabel - %@", objYourVC.TitleLabel);
objYourVC.DescriptionLabel = selectedAnnotation. subtitle;
NSLog(@"objYourVC.DescriptionLabel - %@", objYourVC.DescriptionLabel);


[self.navigationController pushViewController:objYourVC animated:YES];
}



-(IBAction)setMap:(id)sender {

switch (((UISegmentedControl *) sender).selectedSegmentIndex) {
case 0:
mapView.mapType = MKMapTypeStandard;
break;
case 1:
mapView.mapType = MKMapTypeSatellite;
break;
case 2:
mapView.mapType = MKMapTypeHybrid;
break;
default:
break;
}
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end


Then I am going to show you the view that where I want to get the data of the
objYourVC.TitleLabel


This is my RestViewController.h:

#import <UIKit/UIKit.h>
#import "Restaurant.h"
@interface RestViewController : UIViewController

@property (strong, nonatomic) IBOutlet UILabel *TitleLabel;
@property (strong, nonatomic) IBOutlet UILabel *DescriptionLabel;
@property (strong, nonatomic) IBOutlet UIImageView *ImageView;

//@property (strong, nonatomic) IBOutlet NSArray *DetailModal;

@property (weak, nonatomic) IBOutlet UITextView *phoneTextView;
@property (weak, nonatomic) IBOutlet UIButton *webButton;
@property (weak, nonatomic) IBOutlet UITextView *adressTextView;
@property (weak, nonatomic) IBOutlet UIButton *cartaButton;
@property (weak, nonatomic) IBOutlet UITextView *reviewTextView;
@property (weak, nonatomic) IBOutlet UILabel *updateLabel;

@property (nonatomic, strong) Restaurant *DetailModal;

@end


This is my RestViewController.m:

#import "RestViewController.h"
#import <QuartzCore/QuartzCore.h>

@interface RestViewController ()

@end

@implementation RestViewController

- (void)viewDidLoad {
[super viewDidLoad];

NSString *decDate = @"11/2016";
if ([_DetailModal.title isEqualToString:@"Babelia"]) {
_TitleLabel.text = _DetailModal.title;
_DescriptionLabel.text = _DetailModal.desc;
_ImageView.image = [UIImage imageNamed:_DetailModal.image];
_phoneTextView.text = @"(+34) 918 31 71 79";
_adressTextView.text = @"\n• Callejón de Puigcerdá, 6, Madrid, España";
[_webButton setTitle:@"Web" forState:UIControlStateNormal];
[_webButton addTarget:self action:@selector(openWeb_babelia_Url) forControlEvents:UIControlEventTouchUpInside];
[_cartaButton setTitle:NSLocalizedString (@"Menu", nil) forState:UIControlStateNormal];
[_cartaButton addTarget:self action:@selector(openCarta_babelia) forControlEvents:UIControlEventTouchUpInside];
_reviewTextView.text = NSLocalizedString(@"No reviews available.", nil);
_updateLabel.text = [NSString stringWithFormat:NSLocalizedString(@"Updated: %@", nil), decDate];
}

if ([_DetailModal.title isEqualToString:@"Bacira"]) {
_TitleLabel.text = _DetailModal.title;
_DescriptionLabel.text = _DetailModal.desc;
_ImageView.image = [UIImage imageNamed:_DetailModal.image];
_phoneTextView.text = @"(+34) 91 866 40 30";
_adressTextView.text = @"\n• Calle Del Castillo, 16, Madrid, España";
[_webButton setTitle:@"Web" forState:UIControlStateNormal];
[_webButton addTarget:self action:@selector(openWeb_bacira_Url) forControlEvents:UIControlEventTouchUpInside];
[_cartaButton setTitle:NSLocalizedString (@"Menu", nil) forState:UIControlStateNormal];
[_cartaButton addTarget:self action:@selector(openCarta_bacira) forControlEvents:UIControlEventTouchUpInside];
_reviewTextView.text = NSLocalizedString(@"No reviews available.", nil);
_updateLabel.text = [NSString stringWithFormat:NSLocalizedString(@"Updated: %@", nil), decDate];
}
}

-(void)openWeb_babelia_Url{
UIApplication *application = [UIApplication sharedApplication];
NSURL *URL = [NSURL URLWithString:@"http://babeliarestaurante.com/contactar/"];
[application openURL:URL options:@{} completionHandler:^(BOOL success) {
if (success) {
NSLog(@"Opened url");
}
}];
}

-(void)openWeb_bacira_Url{
UIApplication *application = [UIApplication sharedApplication];
NSURL *URL = [NSURL URLWithString:@"http://www.bacira.es/contacto/4585843222"];
[application openURL:URL options:@{} completionHandler:^(BOOL success) {
if (success) {
NSLog(@"Opened url");
}
}];
}

-(void)openCarta_babelia{
UIApplication *application = [UIApplication sharedApplication];
NSURL *URL = [NSURL URLWithString:@"http://babeliarestaurante.com/nuestra-cocina/las-cartas/"];
[application openURL:URL options:@{} completionHandler:^(BOOL success) {
if (success) {
NSLog(@"Opened url");
}
}];
}

-(void)openCarta_bacira{
UIApplication *application = [UIApplication sharedApplication];
NSURL *URL = [NSURL URLWithString:@"http://www.bacira.es/carta/4591994095"];
[application openURL:URL options:@{} completionHandler:^(BOOL success) {
if (success) {
NSLog(@"Opened url");
}
}];
}

@end


The problem is that the method
calloutAccessoryControlTapped:
is not working well because the
RestViewController.m
is not receiving the
objYourVC.TitleLabel
. What can I do?

When I run the project, the
objYourVC.TitleLabel
is good in the
MapViewController.m
(@"Bacira" for example), but when the project goes to
RestViewContoller.m
the
TitleLable
is not good, it shows (@"Label").

I know I have a low level of Xcode and I need your help. I am trying to learn more every day. Can anyone help me? Thank you very much.

Edit: This is my Restaurant.h:

#import <Foundation/Foundation.h>

@interface Restaurant : NSObject

@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *desc;
@property (nonatomic, copy) NSString *image;

- (instancetype)init:(NSString *)title descripiton:(NSString *)description image:(NSString *)image;

@end


And this is my restaurant.m:

#import "Restaurant.h"

@implementation Restaurant

- (instancetype)init:(NSString *)title descripiton:(NSString *)description image:(NSString *)image {
self = [super init];
if (self != nil) {
self.title = title;
self.desc = description;
self.image = image;
}
return self;
}

@end

Answer

You cannot directly deal with IBoutlet , because they have weak reference. o you need to store it an varaible and then in viewDidLoad you need to update the appropriate IBOutlets.

MapViewController.m

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
    RestMapPin *selectedAnnotation = view.annotation;
    NSLog(@"Title of selected pin - %@", selectedAnnotation.title);
    // Here you get the title of selected annotation

    //RestViewController *objYourVC = [[RestViewController alloc]init];
    RestViewController *objYourVC = [self.storyboard instantiateViewControllerWithIdentifier:@"MyIdentifier"];


    objYourVC.DetailModal.pagetitle= selectedAnnotation.title;
    objYourVC.DetailModal.pageDescription = selectedAnnotation.desc;


    [self.navigationController pushViewController:objYourVC animated:YES];
}

RestViewController.h:

#import <UIKit/UIKit.h>
#import "Restaurant.h"
@interface RestViewController : UIViewController

@property (nonatomic, strong) NSString *pageTitle;
@property (nonatomic, strong) NSString *pageDescription ;

@end

RestViewController.m:

#import "RestViewController.h"
#import <QuartzCore/QuartzCore.h>

@interface RestViewController ()

@end

@implementation RestViewController

- (void)viewDidLoad {
    [super viewDidLoad];
     _TitleLabel.text = _pageTitle;
     _DescriptionLabel.text = _pageDescription;


}

@end
Comments