【问题标题】:How to dismissPopoverAnimated on iPad with UIPopoverController in MKMapView (SDK3.2)如何在 MKMapView (SDK3.2) 中使用 UIPopoverController 在 iPad 上解除PopoverAnimated
【发布时间】:2010-04-14 16:57:27
【问题描述】:

我有一个带有注释的 MKMapView(也是一个 UIPopoverControllerDelegate)。此 MapView 在 MKTestMapView.h 文件中具有在 @interface 中定义的 UIPopoverController* popoverController 和在 @interface 部分之外定义的 @property (nonatomic, retain) UIPopoverController* popoverController;。这个控制器是 MKTestMapView.m 文件中的@synthesized,它在- (void)dealloc 部分中发布。此 MapView 中的注释已将 rightCalloutAccessoryViews 定义为以下内容:

- (void)mapView:(MKMapView *)mapView2 annotationView:(MKAnnotationView *)aview calloutAccessoryControlTapped:(UIControl *)control{

...

CGPoint leftTopPoint = [mapView2 convertCoordinate:aview.annotation.coordinate toPointToView:mapView2];

int boxDY=leftTopPoint.y;
int boxDX=leftTopPoint.x;
NSLog(@"\nDX:%d,DY:%d\n",boxDX,boxDY);

popoverController = [[UIPopoverController alloc] initWithContentViewController:controller];
popoverController.delegate = self;
CGSize maximumLabelSize = CGSizeMake(320.0f,600.0f);

popoverController.popoverContentSize = maximumLabelSize;

CGRect rect = CGRectMake(boxDX, boxDY, 320.0f, 600.0f);

[popoverController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];


...

}

现在有趣的部分来了。首先,我不确定我是否需要 maximumLabelSizerect 大小相同。我是 popovercontroller 的新手,所以我是靠耳朵玩的..

好的,弹出窗口显示。现在解雇它。我可以单击 mapView2 上的任何位置,弹出框消失...但是如果用户更改任何内容,我需要用户单击视图中的按钮。啊!

文档显示:

要以编程方式关闭弹出框, 调用dismissPopoverAnimated: popover 控制器的方法。

好吧,问题来了:根据 popoverController 工作方式的定义,您在显示的弹出框的视图内部单击(单击按钮)但必须触发 dismissPopoverAnimated: 方法启动这个弹出视图的控制器,在我的例子中,是 MKTestMapView.m 文件中的popoverController

现在,说了这么多,记住,[popoverController release] 直到:

- (void)dealloc {
 [popoverController release];
 [mapView release];
    [super dealloc];
}

那么,我是否只是在按钮内执行以下操作(混乱但可能有效):

(假设我的弹出视图是一个 TableView)在:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MKTestMapView * mKTestMapView = [[MKTestMapView alloc] init];
[[mKTestMapView popoverController].dismissPopoverAnimated:YES];
}

这是我的问题:我不知道执行上述操作是否会给我一个reference(如果有的话)屏幕上的现有视图 - 因此作为该 popoverController 所有者的视图。如果它像

那样简单
[[[self parentView] popoverController].dismissPopoverAnimated:YES];

我会开枪的,因为我也不认为这是正确的语法!

这应该很容易......但我迷路了。 (可能只是对我正在学习的 iPad 差异如此之多感到沮丧)。

谁能解释一下?

【问题讨论】:

    标签: iphone ipad mkmapview uipopovercontroller


    【解决方案1】:

    我遇到了同样的问题...我的视图顶部有一个整洁的“关闭”按钮 (X),由弹出框加载,但它不起作用。在我的通用应用程序中,它将以新视图的形式呈现,因此代码应该保留。

    我现在所做的是将以下内容添加到我的 detailPinView(弹出框加载的视图)中:

    在detailedPinView.h文件中:

    @interface detailedPinView : UIViewController {
        [...]   
        UIPopoverController *popover;
        [...]
    }
    
    -(void)setPopover:(UIPopoverController*)aPopover;
    

    在detailedPinView.m 文件中:

    - (void)setPopover:(UIPopoverController*)aPopover
    {
        popover = aPopover;
    }
    

    X 按钮使用 IBAction 关闭视图,这就是我在那里所做的:

    在detailedPinView.m 文件中:

    -(IBAction)releaseDetailedView:(UIButton *)sender
    {
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        {
            if (popover != nil)
            {
                [popover dismissPopoverAnimated:YES];
            }
            else {
                NSLog(@"Nothing to dismiss");
            }
        }
        else{
            [self.parentViewController dismissModalViewControllerAnimated: YES];
        }
    }
    

    在加载我的地​​图和弹出视图的类中,我添加了以下代码:

    [...]
    -(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];
    }
    [...]
    

    我不知道这是否是您所希望的答案,我认为这样做可能有点混乱......但是给出时间表这就像一个魅力:)

    【讨论】:

    • 尽管我讨厌这个:如果 (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 因为你不能在通用应用程序或 3.2 之前的应用程序中使用它,我将把它标记为答案 cos这个:[detailController setPopover:aPopover];是我需要的。谢谢
    • 是的,我同意。考虑到我的时间安排,没有太多选择,但会在“未来”改变它。很高兴我能帮上忙!问候,保罗
    • @Jann “因为您不能在通用应用程序或 3.2 之前的应用程序中使用它”。是的你可以。只要您的 Base SDK 是 3.2,它就会在部署在 3.2 之前的设备上时正常运行。
    • 谢谢...这对我很有帮助,而且正是我所需要的 :)
    • 非常有用。这应该是在其自己的视图控制器中关闭弹出框的方法。我使用它通过按下弹出窗口中的导航栏按钮来实现关闭弹出窗口。
    【解决方案2】:

    这是另一个简单的解决方案。

    我发现我们应该按照以下步骤清楚地消除弹出框。

    1. 关闭弹出框。
    2. 释放由弹出框加载的视图。

    在 iOS8 之前,我们几乎所有人都可能先释放一个由弹出框加载的视图,然后我们以编程方式关闭弹出框。 但是,在 iOS8 中,我们会反向执行这些步骤。

    在 iOS8 之前,我的关闭弹出框的代码

    // creating a popover loading an image picker
    picker = [[UIImagePickerController alloc] init];
    ...
    pickerPopover = [[UIPopoverController alloc] initWithContentViewController:picker];
    [pickerPopover presentPopoverFromRect:aFrame inView:aView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    
    // dismissing the popover
    [picker.view removeFromSuperview]; // (1) release a view loaded by a popover
    [picker release], picker = nil;
    
    if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {
        [pickerPopover dismissPopoverAnimated:YES]; // (2) dismiss the popover
    }
    

    在iOS8中,dismissing代码部分应该修改如下,

    if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {
        [pickerPopover dismissPopoverAnimated:YES];  // (2) dismiss the popover first
    }
    
    [picker.view removeFromSuperview]; // (1) and then release the view loaded by the popover
    [picker release], picker = nil;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-18
      • 2011-03-03
      • 1970-01-01
      相关资源
      最近更新 更多