开发者

Placing arrow of uipopovercontroller at annotation point on mapkit

开发者 https://www.devze.com 2022-12-28 20:56 出处:网络
I am trying to get a popover to appear at a map kit annotation point but cannot find a \"rect\" in the annotation view properties to use the rect method of calling uipopovercontroller.If given an anno

I am trying to get a popover to appear at a map kit annotation point but cannot find a "rect" in the annotation view properties to use the rect method of calling uipopovercontroller. If given an annotation on map kit how does one find the appropriate "frame"?

To give paul more information, here is my attempt: I have already used:

- (void)mapView:(MKMapView *)mapView2 annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control{
    NSLog(@"annotationView...");
    MyGizmoClass *myGizmoClass= [MyGizmoClass sharedManager];
    int choic开发者_StackOverflow中文版e = 0;
    for (NSMutableDictionary *locationDictionary in [myGizmoClass searchResultsForResortLocation]) 
    {
        if([view.annotation.title isEqualToString:[locationDictionary objectForKey:@"name"]])
        {

            DetailViewTableStyleController *controller = [[DetailViewTableStyleController alloc] initWithlocationData:[[myGizmoClass searchResultsForResortLocation] objectAtIndex:choice] nibName:@"DetailViewTableStyle" bundle:[NSBundle mainBundle]];

            controller.categoryCode = [locationDictionary objectForKey:@"category_code"] ;

            //create a popover controller
            popoverControllerDetail = [[UIPopoverController alloc] initWithContentViewController:controller];

            // set contentsize
            [popoverControllerDetail setPopoverContentSize:CGSizeMake(320,480)];

            //present the popover view non-modal

            [popoverControllerDetail presentPopoverFromRect:view.rightCalloutAccessoryView.frame inView:mapView2 permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

            [controller release];
            break;
        }
        choice = choice + 1;
    }
}

And... I get a popover at the upper left at the edge of the mapview.

Can anyone tell me why? I am trying to get it to appear near the pin/annotationview.


Okay,

Here is what I found as the only work-around so far:

CGPoint annotationPoint = [mapView2 convertCoordinate:view.annotation.coordinate toPointToView:mapView2];
float boxDY=annotationPoint.y;
float boxDX=annotationPoint.x;
CGRect box = CGRectMake(boxDX,boxDY,5,5);
UILabel *displayLabel = [[UILabel alloc] initWithFrame:box];


[popoverControllerDetail presentPopoverFromRect:displayLabel.frame inView:mapView2 permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[displayLabel release];

The bad part about this is that I am faking putting it at the view of the annotation. I simply get the annotation.coordinate of the annotation view (MKMapKit style coordinates) and convert the coordinates to screen coordinates. Then I create a uilabel (to get a frame-capable construct on the screen) placed where the Annotation View would be. I then tell the popovercontroller to appear at that frame location.

Here is the kicker. I do not add the uilabel to the mapView2. I simply release it once popovercontroller has drawn itself.

Hack, but clean.


The problem with the first example in this thread is in the call to presentPopoverFromRect:inView:permittedArrowDirections:animated:. The value for the inView: parameter is not correct. It should be view.rightCalloutAccessoryView.

That is, the rectangle's coordinates are relative to rightCalloutAccessoryView.

With this change, the behavior will be similar to the maps application which seems right.


If you have the MKAnnotationView, and you imply that you do, then you can use its frame property, as it is a UIView subclass.


Didn't read all the replies... but I had a similar problem. I wanted to show a popover box when I tap the accessory button in the callout bubble. This is how I solved my problem.

First of, I center the map to the annotation I chose, which I think is always a good idea in this case. Then I implement the popover with a fixed size and position it at the correct position (in my opinion).

Here is a part of my code:

-(void)mapView:(MKMapView *)theMapView annotationView:(MKAnnotationView *)pin calloutAccessoryControlTapped:(UIControl *)control
{   
    UIViewController *detailController = [[detailedPinView alloc] initWithNibName:@"detailedPinView" 
                                                                           bundle:nil 
                                                                   annotationView:pin];

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    {

        UIPopoverController* aPopover = [[UIPopoverController alloc] initWithContentViewController:detailController];
        [aPopover setDelegate:self];
        [aPopover setPopoverContentSize:CGSizeMake(320, 320) animated:YES];

        [detailController setPopover:aPopover];
        [detailController release];

        [mapView deselectAnnotation:pin.annotation animated:YES];

        self.popoverController = aPopover;

        [mapView setCenterCoordinate:pin.annotation.coordinate animated:YES];

        [self.popoverController presentPopoverFromRect:CGRectMake(382,498,0,0) inView:self.view  permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
    }
    else
    {
        [self presentModalViewController: detailController animated:YES];
    }


    [detailController release];
}


The issue with presentPopoverFromRect:inView:permittedArrowDirections:animated is that if the content size of the popover is greater than what fits on the screen (because the annotation is close the the edge of the screen, for example), the system will first (at least partially) disregard the rectangle, and put the tip of the arrow somewhere in the middle of the view. I've solved this by doing it this way:

self.popover = [[UIPopoverController alloc] initWithContentViewController:placeDetailViewController];

[self.popover presentPopoverFromRect:CGRectMake(0, 0, 29, 31) inView:view.rightCalloutAccessoryView permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];

The rightCalloutAccessoryView is normally a detail disclosure button, which has a size of 29 by 31. So, what I do, is create a 29 by 31 rectangle, which covers the entire accessory view. Then I present the popover from the accessory view. By increasing the 29 to 40, the popover arrow will be outside the callout bubble, but only if there is enough space to present the entire callout on the screen. If not, the arrow will be moved inside the bubble. To maintain a consistent interface, I left the width at 29.

0

精彩评论

暂无评论...
验证码 换一张
取 消