- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
MKAnnotationView *view = [self.mapView dequeueReusableAnnotationViewWithIdentifier:#"loc"];
return view;
}
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
for (MKAnnotationView *annotationView in views) {
annotationView.canShowCallout = NO;
}
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
MAKRCalloutView *calloutView = [[MAKRCalloutView alloc] initWithNibName:#"ViewM" bundle:nil];
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(10.0, 10.0, 50.0, 50.0)];
[btn setBackgroundColor:[UIColor redColor]];
[btn addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:calloutView.view];
[view addSubview:btn];
}
-(void) buttonClicked:(id)sender{
NSLog(#" %ld button click %# ", (long)[sender tag]);
}
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
for (UIView *subview in view.subviews) {
MAKRCalloutView *calloutView = [[MAKRCalloutView alloc] initWithNibName:#"ViewM" bundle:nil];
if (![subview isKindOfClass:[calloutView.view class]]) {
continue;
}
[subview removeFromSuperview];
}
}
I cannot call get button click event. Even I cannot click on button also. I want to go at other UIViewController by click on button.
I have also tried UITapGestureRecognizer. But its limited to Pin area only.
[button addTarget:self action:#selector(clickEvent) forControlEvents:UIControlEventTouchDown]
And then
- (CustomAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[CustomAnnotation class]])
{
CustomAnnotationView *newAnnotationView = nil;
// determine the type of annotation, and produce the correct type of annotation view for it.
newAnnotationView = [[[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil delegate: targetController] autorelease];
[newAnnotationView setEnabled:YES];
[newAnnotationView setCanShowCallout:NO];
return newAnnotationView;
}
}
#interface CustomAnnotationView : MKAnnotationView
{
}
#end
#implementation CustomAnnotationView
- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier delegate:(id)targetController
{
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
/* Set initial width as you want. ex: 50X50*/
self.frame = CGRectMake(0, 0, Initial_width, Initial_height);
self.backgroundColor = [UIColor redColor];
return self;
}
/* When you tap on an annotation this method is fired*/
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
if(selected){
/* When you select annotation, instead of showing default callout you can increase the width &height of annotation and add your custom view here*/
self.frame = CGRectMake(0, 0, max_width, max_height);
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(6, 0, max_width-10, max_height)];
view.backgroundColor = [UIColor blackColor];
UIButton *but = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *img = [UIImage imageNamed:#"image.png"];
but = CGRectMake(x , y, img.size.width + 20, img.size.height + 15);
[but setImage:img forState:UIControlStateNormal];
[but addTarget:targetController action:#selector(methodName) forControlEvents:UIControlEventTouchDown];
[view addSubview:but];
[self addSubview:view];
}
else {
/* When you tap outside of annotation, set the initial frame for the annotation. and remove the custom view from annotation*/
self.frame = CGRectMake(0, 0, Initial_width, Initial_height);
[view removeFromSuperview];
}
}
Related
I have simple app with Map and pins attached to it. After clicking on pin on map, pinView is created, on wchich I have button with action called let's say ButtonPressed.
I want to know from which pin it was pressed. I tried something like :
(IBAction)ButtonPressed:(id)sender
{
UIButton *but = (UIButton*) sender;
NSLog(#"SEG PLZ SEG CMON %tu",but.superview.tag);
[self performSegueWithIdentifier:#"segu" sender:sender];
}
But it always returns 0, no matter that I set tag for 5.
Okay I post code for adding buttons as you wanted :
- (MKPinAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)myannotation{
MKPinAnnotationView *view = nil;
//MKPinAnnotationView *view=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"HotSpotsLoc"];
if(myannotation !=mapView.userLocation){
view = (MKPinAnnotationView *)
[mapView dequeueReusableAnnotationViewWithIdentifier:#"identifier"];
if(nil == view) {
view = [[MKPinAnnotationView alloc]
initWithAnnotation:myannotation reuseIdentifier:#"identifier"];
}
UIButton *btnViewVenue = [UIButton buttonWithType:UIButtonTypeContactAdd];
[view.rightCalloutAccessoryView setTag:50];
[btnViewVenue addTarget:self action:#selector(ButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
view.rightCalloutAccessoryView=btnViewVenue;
view.enabled = YES;
view.pinColor = MKPinAnnotationColorPurple;
view.canShowCallout = YES;
view.multipleTouchEnabled = NO;
//view.animatesDrop = YES;
UIButton *btnViewwVenue = [UIButton buttonWithType:UIButtonTypeContactAdd ] ;
[btnViewwVenue addTarget:self action:#selector(addImage:) forControlEvents:UIControlEventTouchUpInside];
[view setTag:50];
view.leftCalloutAccessoryView=btnViewwVenue;
view.enabled = YES;
view.pinColor = MKPinAnnotationColorPurple;
view.canShowCallout = YES;
view.multipleTouchEnabled = NO;
}
return view;
}
Setting leftCalloutAccessoryView and rightCalloutAccessoryView does not necessarily add the views as subviews of view. If you need this relationship to be explicit, consider subclassing UIButton.
#interface MyButton : UIButton
#property (weak) MKPinAnnotationView *annotation;
#end
#implementation MyButton
#end
// Then...
(IBAction)ButtonPressed:(id)sender
{
MyButton *but = (MyButton*) sender;
NSLog(#"SEG PLZ SEG CMON %tu",but.annotation.tag);
[self performSegueWithIdentifier:#"segu" sender:sender];
}
I have an annotation on the map. When I select a annotation I will display callout bubble with custom view. Now when I click on the callout bubble I want to go to new view controller but callout view disappears when I tap on the view.
-(void)mapView:(MKMapView *)mapView1 didSelectAnnotationView:(MKAnnotationView *)view
{
NSLog(#"selected");
if(![view.annotation isKindOfClass:[MKUserLocation class]])
{
CustomInfoWindow *calloutView = [[[NSBundle mainBundle]
loadNibNamed:#"infoWindow"owner:self options:nil] objectAtIndex:0];
CGRect calloutViewFrame = calloutView.frame;
calloutViewFrame.origin = CGPointMake(-calloutViewFrame.size.width/2 + 15, -calloutViewFrame.size.height);
calloutView.frame = calloutViewFrame;
[calloutView.imagePlace.layer setBorderColor: [[UIColor orangeColor] CGColor]];
[calloutView.imagePlace.layer setBorderWidth: 3.0];
NSData* imageData = [[NSData alloc] initWithContentsOfURL:
[NSURL URLWithString:#"http://farm3.staticflickr.com/2926/14605349699_67a1d51b80.jpg"]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
[calloutView.imagePlace setImage:image];
[view addSubview:calloutView];
}
}
-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
for (UIView *subview in view.subviews ){
[subview removeFromSuperview];
}
}
I'm no expert but you may want to add a UITapGestureRecognizer to your view.
Use the following code:
UITapGestureRecognizer *tgr = [[UITabGestureRecognizer alloc] initWithTarget:self action:#selector(showNextView)];
calloutView.addGestureRecognizer(tgr);
and
- (void)showNextView {
...
}
The bubble does not have logic, you need use callout accessory. So, use MapView delegate method:
- (void)mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)pin calloutAccessoryControlTapped:(UIControl *)control;
And add callout at viewForAnnotation delegate method. For example:
UIButton *myDetailAccessoryButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
myDetailAccessoryButton.frame = CGRectMake(0, 0, 23, 23);
myDetailAccessoryButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
myDetailAccessoryButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
pinView.rightCalloutAccessoryView = myDetailAccessoryButton;
I hope my answer helps you.
Hello i'm building a mapbased App when i'm tapping on the Accessory i perform a segue to a profile page which gives information about the pin location. Now i have a image in my LeftCalloutAccesoryView which a i want to show on the detail page. Now i'm curious if there is a method to get the image which a set on LeftCalloutAccesoryView. I add the images dynamically.
my accessorycontroltapped code:
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
companytitle = view.annotation.title;
description = view.annotation.subtitle;
thumbprofileimage = view.image;
//thumbprofileimage = [(UIImageView *)view.leftCalloutAccessoryView setImage:pin.image];
//UIImageView *leftIconView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
//leftIconView = [view.leftCalloutAccessoryView [[UIImageView alloc]];
//view.leftCalloutAccessoryView;
[self performSegueWithIdentifier:#"showPlattegrondDetails" sender:self];
}
my set pins code:
- (MKAnnotationView *)mapView:(MKMapView *)mpView viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString *identifier = #"MyLocation";
if ([annotation isKindOfClass:[RouteAnnotation class]]) {
MKPinAnnotationView *annotationView =
(MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc]
initWithAnnotation:annotation
reuseIdentifier:identifier];
} else {
annotationView.annotation = annotation;
}
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
leftIconView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[leftIconView setImage:pin.image];
annotationView.leftCalloutAccessoryView = leftIconView;
//annotationView.leftCalloutAccessoryView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
annotationView.rightCalloutAccessoryView = rightButton;
return annotationView;
}
return nil;
}
Does someone have the solution of getting a reference to the image so i can send this image to the detail page?
You are already part way there with your mapView:annotationView:calloutAccessoryControlTapped: method.
Create a property to keep a reference to the image from the tapped callout:
#property (nonatomic, strong) UIImage *selectedCalloutImage;
And update the delegate method:
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
companytitle = view.annotation.title;
description = view.annotation.subtitle;
thumbprofileimage = view.image;
//thumbprofileimage = [(UIImageView *)view.leftCalloutAccessoryView setImage:pin.image];
//UIImageView *leftIconView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
//leftIconView = [view.leftCalloutAccessoryView [[UIImageView alloc]];
//view.leftCalloutAccessoryView;
// Keep a reference to the callout's image
self.selectedCalloutImage = [(UIImageView *)view.leftCalloutAccessoryView image];
[self performSegueWithIdentifier:#"showPlattegrondDetails" sender:self];
}
Then pass the image to the subsequent controller in the prepareForSegue:sender: method:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showPlattegrondDetails"])
{
DetailViewController *controller = segue.destinationViewController;
controller.image = self.selectedCalloutImage;
}
}
You can then display / use it however you like.
I'm new to ios and Objective-C. Please be a little bit patient with me.
THe functionality in my app, which I'm trying to develop, is a small scrolling toolbar, which contains several buttons, state toggling buttons. Also there is another button above the toolbar which slides in and out the toolbar. The second functionality I achieved successfully, using a view for the whole setup and when the slide button touch up event animates the whole view up and down.
For the scrollview, I wanted to add buttons programmatically, hence I drew an outlet to the class and tried adding a self created button as a subview. However I cannot see the button. Nor can I observe the scrollview sliding.
THe following is the way I'm adding the button:
Also, my total view for the above functionality is very less in size than the total view controller
UIButton *button = [[UIButton alloc] init];
button.titleLabel.text = #"hello";
[_scrollTop setContentSize:self.view.frame.size];
[_scrollTop addSubview:button];
The two images down, I hope, should help you understand the functionality I'm trying to develop. If anybody is aware of existence of similar functionality, please do direct me.
Edit: Code totally is
//
// HCILocationViewController.m
// app2
//
// Created by Ravi Vooda on 13/03/13.
// Copyright (c) 2013 housing.co.in. All rights reserved.
//
#import "HCILocationViewController.h"
#import "HCIAnnotationViewController.h"
#interface HCILocationViewController ()
#property int widMap;
#property BOOL showExploreOptions;
#end
#implementation HCILocationViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
_mapLocationView.delegate = self;
MKPointAnnotation *annotation = [[HCIAnnotationViewController alloc]
initwithHouse:[self singleHome]];
[_mapLocationView addAnnotation:annotation];
_widMap = 10000;
_showExploreOptions = NO;
/*
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(aMethod:)
forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);//give values whatever you want.
[_scrollTop addSubview:button];
*/
[self addButtonsToScrollView];
}
- (void)addButtonsToScrollView
{
NSInteger buttonCount = 4;
CGRect buttonFrame = CGRectMake(5.0f, 5.0f, self.scrollTop.frame.size.width-10.0f, 40.0f);
for (int index = 0; index <buttonCount; index++) {
UIButton *button = [[UIButton alloc]initWithFrame:buttonFrame];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:index+1];
NSString *title = [NSString stringWithFormat:#"Button %d",index+1];
[button setTitle:title forState:UIControlStateNormal];
[self.scrollTop addSubview:button];
buttonFrame.origin.y+=buttonFrame.size.height+5.0f;
}
CGSize contentSize = self.scrollTop.frame.size;
contentSize.height = buttonFrame.origin.y;
[self.scrollTop setContentSize:contentSize];
}
- (void)buttonPressed:(UIButton *)button
{
NSLog(#"button pressed");
switch (button.tag) {
case 1:
//Do something
break;
default:
break;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(MKAnnotationView*) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
NSString *identifier = #"currDetailsIdentifier";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[_mapLocationView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc]
initWithAnnotation:annotation
reuseIdentifier:identifier];
} else {
annotationView.annotation = annotation;
}
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
return annotationView;
}
-(void) mapViewDidFinishLoadingMap:(MKMapView *)mapView
{
MKMapRect zoomRect = MKMapRectNull;
for (id <MKAnnotation> annotation in mapView.annotations) {
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(
annotationPoint.x - (_widMap / 2),
annotationPoint.y - (_widMap/2),
_widMap,
_widMap);
if (MKMapRectIsNull(zoomRect)) {
zoomRect = pointRect;
} else {
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
}
[mapView setVisibleMapRect:zoomRect animated:YES];
}
-(void) setMyHouse:(NSDictionary *)singleHouse {
self.singleHome = singleHouse;
}
- (IBAction)toggleExploreOptionsView:(UIButton *)sender {
sender.selected = !sender.selected;
if (_showExploreOptions){
NSLog(#"Close Options");
[UIView animateWithDuration:0.2 animations:^{
_exploreView.frame = CGRectMake(_exploreView.frame.origin.x, _exploreView.frame.origin.y + _exploreOptionsView.frame.size.height, _exploreView.frame.size.width, _exploreView.frame.size.height + _exploreOptionsView.frame.size.height);
}];
}
else {
NSLog(#"Open Options");
[UIView animateWithDuration:0.2 animations:^{
_exploreView.frame = CGRectMake(_exploreView.frame.origin.x, _exploreView.frame.origin.y - _exploreOptionsView.frame.size.height, _exploreView.frame.size.width, _exploreView.frame.size.height - _exploreOptionsView.frame.size.height);
}];
}
_showExploreOptions = !_showExploreOptions;
}
#end
If I understood your question correctly you need to have view which should show up and collapse on a button click event. When the view is shown, it should have a scrollable list of buttons. And you are asking help to show many buttons to scrollView.
Demo Source Code
- (void)addButtonsToScrollView
{
NSInteger buttonCount = 5;
CGRect buttonFrame = CGRectMake(5.0f, 5.0f, self.scrollTop.frame.size.width-10.0f, 40.0f);
for (int index = 0; index <buttonCount; index++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setFrame:buttonFrame];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:index+1];
NSString *title = [NSString stringWithFormat:#"Button %d",index+1];
[button setTitle:title forState:UIControlStateNormal];
[self.scrollTop addSubview:button];
buttonFrame.origin.y+=buttonFrame.size.height+5.0f;
}
CGSize contentSize = self.scrollTop.frame.size;
contentSize.height = buttonFrame.origin.y;
[self.scrollTop setContentSize:contentSize];
}
- (void)buttonPressed:(UIButton *)button
{
switch (button.tag) {
case 1:
//Do something
break;
default:
break;
}
}
I try to call a method when the annotation view (and only the annotation view) is clicked.
- (void)mapView:(MKMapView *)m didSelectAnnotationView:(MKAnnotationView *)view {
[self openDetailView];
}
But what i noticed, is that this method (openDetailView) is called only when i select the PIN, means before the annotation view gets displayed. How can i fire that method on callout click? Thanx in advance.
By adding button with arrow instead of callout:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if ([annotation isMemberOfClass:[MKUserLocation class]]) {
return nil;
}
MKPinAnnotationView *v =[[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"ku"] autorelease];
UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
button.frame = CGRectMake(0, 0, 24, 24);
Shop *shop = [(ShopAnnotation *)annotation myShop];
button.tag = [shop.ID intValue];
[button addTarget:self action:#selector(callOutPressed:) forControlEvents:UIControlEventTouchUpInside];
[button setImage:[UIImage imageNamed:#"map_arr_right.png"] forState:UIControlStateNormal];
v.rightCalloutAccessoryView = button;
v.canShowCallout = YES;
return v;
}
- (void) callOutPressed:(id)sender {
NSLog(#"callout pressed");
}