MKPinAnnotationView - different actions in different Pins - iphone

I have a question about the MKPinAnnotationView. First of all I entered coordinates of the pins and after that called the viewForAnnotation to build them and also add them the a right button.
But my question is how can I select different actions for those pins?
When I look for the button tag in NSLog, it always shows 0 for every pin so I can't make it with tags.
Here is the code of the button if it means something:
for (int i=0;i<=[[mapview annotations]count];i++) {
pinView.tag = i ;
rightButton.tag=i;
}

You don't need to (and should not) use tags.
Instead, in the action method, you can determine which annotation was selected and then execute different logic based on that.
You don't even need to create your own action method. When a callout button is tapped, the map view will call its calloutAccessoryControlTapped delegate method which gives you a reference to the annotation (ie. view.annotation). If you decide to use the delegate method, remove the addTarget from viewForAnnotation and just implement the delegate method.
If you want to use your own action method for some reason, you can determine which annotation was selected by looking at the map view's selectedAnnotations property. The selected annotation will be at index 0 (be sure to first check that the array's count is not zero).
For sample code of all the above, see this question:
How to keep data associated with MKAnnotation from being lost after a callout pops up and user taps disclosure button?

Related

iOS; Swift; How do I keep an annotation open even when the screen is tapped within a MapBox map view?

I have my screen split; 50% for the map and 50% for a list of elements. As the list of elements is scroll, the annotation will pop around the map based off whichever element is in the top of the list. This part is working fine.
However, when the user taps on the map, I don't want the annotation to disappear. I really want the user's tap to interactive with the MapView instead of the AnnotationView.
Is this possible? If so, can someone point me in the right direction? Thanks.
You have a couple of options:
You can intercept the built-in tap gesture recognizer or add a custom tap gesture recognizer. When the user taps the map, check if an annotation is selected. If one is selected, call mapView:selectAnnotation: to keep it selected.
You can call mapView:selectAnnotation: in the relevant mapView:deselectAnnotation: or mapView:deselectAnnotationView: delegate method.

Correct behaviour of Mouse down inside row of NSTableView?

I have a NStableView which is NSView based. In each row also have a NSImageView which is subview of NSView. I have subclassed this NSImageView then overrided mouseDown method. The problem is tableViewSelectionDidChange is also getting fired when user clicks on this imageview. I want only mouseDown to be called but not tableViewSelectionDidChange.
If I set selectionHighlightStyle of table to NSTableViewSelectionHighlightStyle.None then only mouseDown of image view is called. And if I don't give selectionHighlightStyle to NSTableViewSelectionHighlightStyle.None then both mouseDown of imageview and tableViewSelectionDidChange are getting called. Setting selectionHighlightStyle to none seems to solve my problem but is this correct approch? Or I am getting this behaviour because of some bug in appkit?
Also I can't find this behaviour documented somewhere.
I think the correct approach you be to subclass NSTableView and override the NSResponder method -(BOOL)validateProposedFirstResponder:(NSResponder *)responder forEvent:(NSEvent *)event
You'll have a finer control over which view will get the mouse event, and won't have to resort to "hackery" like changing the table view selection style.
From the apple docs:
Specifying How Subviews Should Respond to Events
Views or controls in a table sometimes need to respond to incoming events. To determine whether a particular subview should receive the current mouse event, a table view calls validateProposedFirstResponder:forEvent: in its implementation of hitTest. If you create a table view subclass, you can override validateProposedFirstResponder:forEvent: to specify which views can become the first responder. In this way, you receive mouse events.
The default NSTableView implementation of validateProposedFirstResponder:forEvent: uses the following logic:
Return YES for all proposed first responder views unless they are instances or subclasses of NSControl.
Determine whether the proposed first responder is an NSControl instance or subclass.
If the control is an NSButton object, return YES.
If the control is not an NSButton, call the control’s hitTestForEvent:inRect:ofView: to see whether the hit area is trackable (that is, NSCellHitTrackableArea) or is an editable text area (that is, NSCellHitEditableTextArea), and return the appropriate value. Note that if a text area is hit, NSTableView also delays the first responder action.
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TableView/RowSelection/RowSelection.html#//apple_ref/doc/uid/10000026i-CH6-SW9

iPhone - Replace GoogleMap MapKit user's direction blue dot with spinning arrow

How may I show an arrow that shows the users direction instead (over ?) the existing blue dot in the MapKit on a GoogleMap view ?
From the documentation of the mapView:viewForAnnotation: delegate method:
If the object in the annotation parameter is an instance of the MKUserLocation class, you can provide a custom view to denote the user’s location. To display the user’s location using the default system view, return nil.
So you should do just that. Check the class of the annotation for MKUserLocation and in case of a successful match, return a custom view. You must take care to update this view yourself whenever the user's heading changes.

Custom MKAnnotationView - How to capture touches and NOT dismiss the callout?

I have a custom MKAnnotationView subclass. It is showing the view exactly as I want it to. In that view, I have a button. I want to capture events on the button to perform an action. This works just fine.
However, I do NOT want the callout to be dismissed or disappear. Basically, touching the button in the callout will start playing a sound, but I want to leave the annotation up so the user can press stop if they want to, without having to touch the map pin again to bring the annotation back up. In another instance, I want the button touch to animate more details in the callout, so I definitely don't want to dismiss the callout at that point.
How can I keep the callout from disappearing whenever the user selects the callout or a button inside the callout?
This may not be the best solution, but it definitely works. First off, I tried a number of things, like observing for context and such, but I never got past crashing, and it seemed cumbersome. So, this is what I did:
I first specified what the controlling factor was for keeping an alert viewable. In my case, I created a custom annotation view, and whenever the user clicks a button on that custom view, I want it to stay visible, and maybe even change the content. So, I set a delegate on that custom view so that my map can know when something changes. In my map view controller, I catch that message and set a class member variable to true to signify that I want the annotation view to stay.
NOTE: This will happen before the selection messages occur.
Now, in my didDeselectAnnotation method, I check the boolean value. If I want to keep it visible, I opt to NOT remove my annotation, I reset the boolean value, and I re-select the annotation manually, setting animation to NO. This lets the annotation view "stay" visible--maybe a cheat, but the user can't see the difference. Whenever that boolean value says that deselection is ok, I simply remove the annotation and all is well.
So, the workflow is this:
Touch pin
CustomAnnotationView is displayed
User clicks a button on CustomAnnotationView, which notifies the delegate (mapView) that the
action occurred
Set the class boolean value to know that you want to keep the annotation around
mapView then calls didDeselectAnnotation method
In didDeselectAnnotation method, use conditional to decide if you should remove the annotation, or keep it around by not removing the annotation and manually re-selecting it without animation.
I hope this helps others. It took me a while to figure this out, so I hope it saves you time.
If you find a better solution, by all means, please post it here!
you can suppress callout closing by using hittest, check this following post.
Detect tap on title of callout

how to detect a callout of an annotation is showing on mapview?

I have a checkin related app. When user clicks a venue on map, callout will popup and show its name and address. At the same time, if the venue is within 1000m from current location, a check in button will be displayed.
To a venue that can checkin, all I want is,
when callout is popup, check in button shows. when callout is disappear, that button disappears too.
Now show button works well, but I don't know how to detect callout visible status. Is there any callback method that callout show/hide?
Thanks in advance!
Callout appears when annotation is selected - you can use mapView:didSelectAnnotationView: method in delegate to track that event. Callout hides when annotation is deselected - use mapView:didDeselectAnnotationView: method to track that event.
As you can see here it is about selected property of MKAnnotationView, which is saying that If the property contains YES, the annotation view is displaying a callout bubble.
You may additionally implement an observer for this property, to implement your functionality.