将uipopovercontroller的箭头放置在mapkit的注释点

Posted

技术标签:

【中文标题】将uipopovercontroller的箭头放置在mapkit的注释点【英文标题】:Placing arrow of uipopovercontroller at annotation point on mapkit 【发布时间】:2010-05-04 06:36:34 【问题描述】:

我试图让弹出框出现在地图工具包注释点,但在注释视图属性中找不到“矩形”以使用调用 uipopovercontroller 的 rect 方法。如果在地图套件上给出注释,如何找到合适的“框架”?

为了给保罗更多信息,这是我的尝试:我已经使用过:

- (void)mapView:(MKMapView *)mapView2 annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
    NSLog(@"annotationView...");
    MyGizmoClass *myGizmoClass= [MyGizmoClass sharedManager];
    int choice = 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;
    

而且...我在地图视图边缘的左上角看到一个弹出框。

谁能告诉我为什么?我试图让它出现在 pin/annotationview 附近。

【问题讨论】:

【参考方案1】:

好的,

这是迄今为止我发现的唯一解决方法:

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];

关于这个的不好的部分是我假装把它放在注释的视图中。我只需获取注释视图的 annotation.coordinate(MKMapKit 样式坐标)并将坐标转换为屏幕坐标。然后,我创建了一个 uilabel(以在屏幕上获得一个支持框架的构造),并将其放置在 Annotation View 所在的位置。然后我告诉 popovercontroller 出现在该帧位置。

这是踢球者。我没有将 uilabel 添加到 mapView2。一旦 popovercontroller 绘制了自己,我就简单地释放它。

破解,但干净。

【讨论】:

你不需要 UILabel。 displayLabel.frame 只是返回一个 CGRect 所以你可以直接使用box presentPopoverFromRect:inView:permittedArrowDirections:animated 的问题是,如果弹出框的内容大小超过屏幕的大小(例如【参考方案2】:

此线程中第一个示例的问题在于对 presentPopoverFromRect:inView:permittedArrowDirections:animated: 的调用。 inView: 参数的值不正确。应该是 view.rightCalloutAccessoryView。

即矩形的坐标是相对于rightCalloutAccessoryView的。

通过此更改,行为将类似于看起来正确的地图应用程序。

【讨论】:

【参考方案3】:

如果你有MKAnnotationView,并且你暗示你有,那么你可以使用它的frame 属性,因为它是UIView 的子类。

【讨论】:

请检查我添加的新代码以获取更多信息 Paul。感谢您的帮助。 你应该打印出两个帧值;我怀疑您正在使用来自不匹配视图的坐标。使用 convertRect:toView: 确保它们匹配。【参考方案4】:

没有阅读所有回复...但我遇到了类似的问题。当我点击标注气泡中的附件按钮时,我想显示一个弹出框。 这就是我解决问题的方法。

首先,我将地图以我选择的注释为中心,我认为在这种情况下这始终是一个好主意。然后我以固定大小实现弹出框并将其放置在正确的位置(在我看来)。

这是我的代码的一部分:

-(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];

【讨论】:

我用我认为更好的方法回答了我自己的问题。通过仅使用 mkannotation 的坐标,我让 iPad iPhoneOS 仍然对弹出框的位置做出最佳决定。我认为这在大多数情况下会更好(阅读 iPhoneOS 更新)..但感谢您的回复。【参考方案5】:

presentPopoverFromRect:inView:permittedArrowDirections:animated 的问题在于,如果弹出框的内容大小大于适合屏幕的大小(例如,因为注释靠近屏幕边缘),系统将首先(至少部分)忽略矩形,并将箭头的尖端放在视图中间的某个位置。我已经通过这种方式解决了这个问题:

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

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

rightCalloutAccessoryView 通常是一个细节显示按钮,大小为 29 x 31。所以,我要做的是创建一个 29 x 31 的矩形,它覆盖整个附件视图。然后我从附件视图中显示弹出框。通过将 29 增加到 40,弹出箭头将位于标注气泡之外,但前提是有足够的空间在屏幕上显示整个标注。如果没有,箭头将在气泡内移动。为了保持界面一致,我将宽度设置为 29。

【讨论】:

以上是关于将uipopovercontroller的箭头放置在mapkit的注释点的主要内容,如果未能解决你的问题,请参考以下文章

如何在顶部左侧有 UIPopOverController 的箭头?

如何使 UIPopoverController 自动改变其箭头方向

旋转时,从 UITableViewCell 显示的 UIPopoverController 放置不正确

UITableViewCell 上的 UIPopoverController

UIPopoverController 位置

iPad UIWebView 在 href 链接坐标处定位 UIPopoverController 视图