【问题标题】:UIPopoverController dismisses without delegate callUIPopoverController 在没有委托调用的情况下关闭
【发布时间】:2023-03-10 19:12:01
【问题描述】:

我有一个地图视图,我根据popovercontroller 中的开关添加和删除annotations。当我在popover 之外触摸时,它会正确关闭并调用delegate 方法popoverControllerDidDismissPopover: 我遇到的问题是,当我在popover 中切换开关时(在弹出视图中触摸),如果我我正在从地图中删除annotations,它的行为正确并且弹出框保持可见,但是如果我将annotations 添加到地图视图中,那么popover 就会消失并且delegate 方法不会被调用。有没有人遇到过这种行为?

开关的开启和关闭代码之间的唯一区别是一个从数组中删除annotations,而另一个添加annotations。这只是将annotations 添加到地图视图时的问题。任何帮助或建议将不胜感激。

popover 的显示方式如下:

-(IBAction)toggleMapFiltersView:(id)sender
 {
    LayerPopoverViewController *popOverViewController = [[LayerPopoverViewController alloc] init];
    [popOverViewController setDelegate:self];
    [popOverViewController setBranchesShowing:branchesShowing];
    [popOverViewController setSchoolsShowing:schoolsShowing];

    [layersButton setSelected:YES];

    popoverController = [[UIPopoverController alloc]   initWithContentViewController:popOverViewController];


    [popoverController setDelegate:self];
    [popOverViewController release];
    [popoverController presentPopoverFromRect:layersButton.frame
                                       inView:[self view] 
                     permittedArrowDirections:UIPopoverArrowDirectionAny 
                                     animated:YES];
}

这是从弹出视图中调用的方法:

-(IBAction)toggleSchools:(id)sender
{
    if ([self.delegate respondsToSelector:@selector(didChangeSchoolsDisplaySettingWithVisible:)])
    {
        if ([schoolsSwitch isOn])
        {
        [self.delegate didChangeSchoolsDisplaySettingWithVisible:YES];
             self.schoolsShowing = YES;
        }
        else
        {
            [self.delegate didChangeSchoolsDisplaySettingWithVisible:NO];
            self.schoolsShowing = NO;
        }
    }
}

这就是它所指的方法:

-(void)didChangeSchoolsDisplaySettingWithVisible:(BOOL)visible
{
    if (visible == YES)
    {
        schoolsShowing = YES;
        if (self.schoolArray != nil && [self.schoolArray count] > 0)
        {
            for (MySchool *school in self.schoolArray)
            {
                [mapView addAnnotation:school];
            }
        }
    }
    else
    {
        schoolsShowing = NO;
        for (id<MKAnnotation> annotation in mapView.annotations)
        {
            if ([annotation isKindOfClass:[MySchool class]])
            {
                [mapView removeAnnotation:annotation];
            }
        }
    }
}

【问题讨论】:

  • 你能不能贴一些代码,让我们看看发生了什么?
  • 添加了涉及的两个方法
  • 请告诉我们弹出框是如何设置和显示的。
  • 因此,当您从 UIPopoverController 中调用 -(IBAction)toggleSchools 时,它会在不调用 didDismiss 的情况下解散?在我看来,这确实是出乎意料的行为。不应该调用解除回调的唯一原因是您自己以编程方式解除它。 (请参阅 UIPopoverControllerDelegate 的 Apple 文档)是否有一些底层代码调用告诉弹出框关闭?我认为没有收到任何内存警告?没有其他奇怪的不稳定行为?
  • @NonatomicRetain 他显然没有使用 ARC,因为在第一块代码中有一条发布消息。无论如何,这里发布的代码不足以预测问题;弹出框的创建和显示保留计数为 1,因此不应在不调用 shouldDismiss 的情况下随机释放它。 @Olie 有一个很好的建议;您也可以在 toggleSchools 的开头返回,看看它是否与您正在使用 mapView 的操作无关。

标签: iphone ios mkmapview uipopovercontroller


【解决方案1】:

为什么首先使用弹出框?控制 customView 会更容易。

您可以创建一个自定义 popupView,并将其放置在您喜欢的坐标上方。 弹出窗口有一个关闭按钮,并委托调用此操作。

这是一些代码(在本例中,坐标来自标记,mapView 是谷歌的)。您还必须将坐标转换为 CGPoint。

UIAnnotationView *annotation = [[UIAnnotationView alloc] initWithFrame:CGRectMake(0,0,100,100)];
                  annotation.delegate = self;
                  annotation.tag = 101;

CGPoint point = [mapView.projection pointForCoordinate:marker.position];
        annotation.origin =  CGPointMake(point.x - annotation.width / 2, point.y - annotation.height - MARKER_DEFAULT_SIZE);
        [mapView addSubview:annotation];

UIAnnotaionView closeButtonClicked 委托:

- (void)annotationViewCloseButtonClicked:(UIAnnotationView *)annotationView
{
    [[_mapView viewWithTag:101] removeFromSuperview];
}

要在触摸地图中的其他点时关闭 popupView 覆盖此委托:

- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate
{
    [[_mapView viewWithTag:101] removeFromSuperview];
}

【讨论】:

  • Popovers 确实对他们有一种系统性的感觉。
  • 没错,但它是一个有效的替代方案。另外,我想找到类似popover的设计很容易..
【解决方案2】:

您是否尝试过另一种委托方法

- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController {
    // do some stuff here and decide whether to dismiss or not
    return YES; //or No depending on your condition
}

它会询问你是否要关闭 popOver 控制器。 每次 popoverviewcontroller 即将关闭时都会调用它

否则,您可以在向 mapview 添加注释时调用方法。无论如何,您知道弹出窗口正在解雇。当弹出控制器关闭时执行相同的工作。正如你正在做的那样

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多