multiple annotation have issue to get selected index annotation - iphone

I have displayed multiple annotation successfully in mapView in my iphone application, but I have problem too .. In top of the screen I have two Tab Map and List . map display all annotation in map and list display those data in Tableview which is display in map. when I click on particular cell i get all the particular detail of that cell.but when I try to get id from Tap annotation my array getting lots of id after comparison of name because we have same name in my array list so how can I differentiate from annotation tag. How to set tag of annotations ?

In the calloutAccessoryControlTapped delegate method, use view.annotation to access the annotation that was tapped.
If you have a custom annotation class, you can cast it to easily access the properties (you may also want to first check if the annotation tapped is an instance of the class you're interested in--important if you're using multiple annotation classes):
if ([view.annotation isKindOfClass:[TagMark class]]) {
TagMark *tm = (TagMark *)view.annotation;
NSLog(#"tm.someProperty = %#", tm.someProperty);
}

Related

Swift PDFKit add annotation to beginning of page annotation array?

In Swift PDFKit is there a way to add an annotation to to the beginning of the page annotations array. I want to add my annotation to the beginning of the array because it is an image and I have other annotations I want to be able to edit that are ontop of it.
The only way I can find to add an annotation is with the following, but it adds it to the end of the array overlaying all other annotations that need to be editable.
page.addAnnotation(myannotation)
Thanks for any help!!
Here is a terrible solution, but it works . . .
I made a tmp list of all the annotations, remove all annotations on the page, and then added them all back with the image added first.
let list = page.annotations
for i in page.annotations{
page.removeAnnotation(i)
}
// add myannotation first
page.addAnnotation(myannotation)
// add other annotations back
for i in list {
page.addAnnotation(i)
}

How to access callout view on clicking on map annotation using swift in xctest

I want to access callout views and do some UIAutomation on those views. I'm able to click on map markers/annotations but not able to access the callout view.
The following code used to tap on the marker:
let marker = app.otherElements.matching(identifier: "mapMarker").element(boundby: 0)
marker.tap();
After this, I'm getting the callout view of the respected marker/annotation.
I need to access that callout.
Please suggest me on this.
You should create a breakpoint after the callout is snown,
then type po print(app.debugDescription) (or simply po app in XCode 11) in lldb in order to view the whole hierarchy of UI elements.
Locate the needed element and access it further in code.
Also, consider rewriting your marker code in a shorter way:
let marker = app.otherElements["mapMarker"].firstMatch
Please notice firstMatch aborts search of elements after it found the first one.
Drop firstMatch, if you want to check that the element is unique
let marker = app.otherElements["mapMarker"]
Same as Smart Monkey said, but to add more code based off the comment from ablarg:
Ex: "mapMarker" being the accessibility ID for the element
let mapMarker = app.maps.otherElements["mapMarker"].firstMatch
let mapMarkerExists = mapMarker.waitForExistence(timeout: 3)
if mapMarkerExists {
mapMarker.tap()
}
waitForExistence(timeout:) returns a bool, so if the element appears before the timeout expires (it finds the element) take action (tap) on the element.
Make sure the element is enabled for accessibility and has the accessibility ID set.

Passing data from one view controller to another without using Segue

I have a UITableView (let’s say class “Parent” which is in view "screen 1"). When I click on one of the Parent’s cell's, I’m displaying another UITableView (let’s call it class “child” in view “Screen2”). Parent and child are connected through “segue” and I’m able to pass the data using “segue”.
For example, parent is having cell – “Cell1” and on touch “Cell1”, I’m getting “Cell11”,”Cell12”,”Cell13” [this is “screen2, table view object”].
Now, there are some descriptions associated with “Cell11” (Once I touched “Cell11”) and i'd like it to display Cell11’s description in another view controller (“screen3”). Here, to pass information between “screen2” to “screen3” I'd rather not to use a “Segue”.
How can I do this?
There are two ways in which you can present a new screen.
1) with the interface builder, here you use a segue to pass something onto the new screen.
2) manually instantiating it, after it is instantiated you can just present it.
Considering you do not want to use method 1, you can use method two like this:
ScreenBClass *screenB = [self.storyboard instantiateViewControllerWithIdentifier:#"screenB"];
screenB.objectPointerInOtherClass = self.objectIWantToPass;
[self screenB animated:YES];

MKAnnotation "title" property, how to suppress when using left/rightCalloutAccessoryView?

The situation in iOS 5 appears to be that a callout will not be displayed for a MKAnnotationView when the id's title is nil. MKAnnotationView Class Reference:
(If the annotation’s title method returns an empty string, the
annotation view is treated as if its enabled property is set to NO.)
What I want to do is display a callout entirely composed of views, no NSStrings. There will be a string on my leftCalloutAccessoryView but moving it to title is going to mess up the design. For one thing it is not in the system font but must match the rest of the app.
Can a MKAnnotationView be made to pop up a callout composed entirely of the views returned by leftCalloutAccessoryView and rightCalloutAccessoryView, with no title between?
try this:-
annotation.title=#" ";
don't set the title string to empty, set one space character in string, in this way the no string will be shown in title and your callout will be displayed properly.

MKMapView loading all annotation views at once (including those that are outside the current rect)

UPDATE
It looks like this problem has been quietly fixed in iOS 4.3. Up to this point, the distance that was considered "far enough" for an annotation to be recycled seemed to be hundreds of miles, even when zoomed in very closely. When I build my app with the iOS 4.3 SDK, annotations are recycled based on more reasonable limits.
Has anyone else run into this problem? Here's the code:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(WWMapAnnotation *)annotation {
// Only return an Annotation view for the placemarks. Ignore for the current location--the iPhone SDK will place a blue ball there.
NSLog(#"Request for annotation view");
if ([annotation isKindOfClass:[WWMapAnnotation class]]){
MKPinAnnotationView *browse_map_annot_view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"BrowseMapAnnot"];
if (!browse_map_annot_view) {
browse_map_annot_view = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"BrowseMapAnnot"] autorelease];
NSLog(#"Creating new annotation view");
} else {
NSLog(#"Recycling annotation view");
browse_map_annot_view.annotation = annotation;
}
...
As soon as the view is displayed, I get
2009-08-05 13:12:03.332 xxx[24308:20b] Request for annotation view
2009-08-05 13:12:03.333 xxx[24308:20b] Creating new annotation view
2009-08-05 13:12:03.333 xxx[24308:20b] Request for annotation view
2009-08-05 13:12:03.333 xxx[24308:20b] Creating new annotation view
and on and on, for every annotation (~60) I've added. The map (correctly) only displays the two annotations in the current rect. I am setting the region in viewDidLoad:
if (center_point.latitude == 0) {
center_point.latitude = 35.785098;
center_point.longitude = -78.669899;
}
if (map_span.latitudeDelta == 0) {
map_span.latitudeDelta = .001;
map_span.longitudeDelta = .001;
}
map_region.center = center_point;
map_region.span = map_span;
NSLog(#"Setting initial map center and region");
[browse_map_view setRegion:map_region animated:NO];
The log entry for the region being set is printed to the console before any annotation views are requested.
The problem here is that since all of the annotations are being requested at once, [mapView dequeueReusableAnnotationViewWithIdentifier] does nothing, since there are unique MKAnnotationViews for every annotation on the map. This is leading to memory problems for me.
One possible issue is that these annotations are clustered in a pretty small space (~1 mile radius). Although the map is zoomed in pretty tight in viewDidLoad (latitude and longitude delta .001), it still loads all of the annotation views at once.
Thanks...
What you would expect is some kind of "clipping" of the annotation views based on the current region the map displays.
This is NOT the way the dequeueReusableAnnotationViewWithIdentifier selector works.
From its documentation :
As annotation views move offscreen, the map view moves them to an internally managed reuse queue. As new annotations move onscreen, and your code is prompted to provide a corresponding annotation view, you should always attempt to dequeue an existing view before creating a new one.
So the reusable mechanism only makes sense when you invoke a sequence like :
//this will create 1000 annotation views
[theMap addAnnotations:my1000annotations];
//this will move them offscreen (but some annotation views may be kept internally for further reuse)
[theMap removeAnnotatios:theMap.annotations];
//when adding back again some annotations onscreen, some of the previous annotation views will be reused.
[theMap addAnnotations:someNew400annotations];
In you case, the way I would implement the clipping (to display only the annotation for the current displayed region) is :
Add a delegate to your mapView and implement the - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated method to get informed when the region has changed
iterate through all your objects to get the ones that match this region
addAnnotations to your map for only those objects (you can implement a kind of merge between the previously displayed annotations and the new one or simply restart from scratch , remove all annotations, and set the new ones
Of course, when the user zooms out quite a lot and that the scope of the region is too big (too many pins to be displayed), then you have to take a decision : do I displayed all the annotations views (and take the risk that the display on the map does not give much info) or do I set a message to the user saying "zoom in to get pins" or whatever. But this is another story... ;)
Not sure if this will help, but you mentioned memory issues due to load of ~60 objects. Is there a way to conditionally load each object based on the current map region center and current map region span?
// :)