iPad - 关闭UIPopoverController

8

我是一名有用的助手,可以为您进行文本翻译。

我有一个按钮在UIPopoverController的内容中。这个按钮运行一个名为myAction的方法。

myAction的形式如下:

- (void) myAction:(id)sender 

所以,myAction方法接收调用者按钮的ID。

现在,在这个方法内部,我想要关闭UIPopoverController,但是我只有调用者按钮的ID。请记住,按钮位于UIPopoverController内部。

是否有一种方法可以根据我已经拥有的按钮ID发现UIPopoverController的ID?

谢谢。

4个回答

19

很遗憾,标准实践中没有此功能。你可以尝试向响应器栈上层查找它,但这是一种hack方法,存在漏洞,非常混乱。

如果你想通过按按钮来关闭弹出框,某个相关的地方应该保存对该弹出框的引用,通常应该是弹出框的所有者(而不是弹出框内显示的控制器)。当按下按钮时,它可以向所有者控制器发送消息,然后所有者控制器可以关闭弹出框。

你可能会想让在弹出框内显示的控制器成为其自己弹出框的所有者,但这种编码方式很脆弱,会变得混乱(再次),可能会导致保留回路,以至于两者都无法释放。


3
在这个答案中,第二段非常重要。请记住,根据iPad编程指南:“请注意,您的责任是存储一个对弹出窗口控制器的引用,以便您可以关闭它。系统不会默认提供一个。” 因此,在父视图进入dealloc阶段之前,请不要对其进行“release”操作(无论如何都会导致崩溃)。(这是我的安全方法)。 - Jann
只需使用[self dismissViewControllerAnimated:YES completion:nil];。 "呈现视图控制器负责解除其呈现的视图控制器。如果您在呈现的视图控制器本身上调用此方法,则它会自动将消息转发给呈现的视图控制器。" - T.J.

5
您可以通过使用KVC访问“popoverController”来访问呈现的popoverController。
[[self valueForKey:@"popoverController"] dismissPopoverAnimated:YES]

1
聰明,但是否有可能被標記為“使用私有API”,即使從技術上來說並沒有使用私有API,應用程序會被拒絕呢? - Chintan Patel
是的,@Chintan。如果AppStore检测到您的代码使用了他们的“私有API”,则可能会被拒绝。 - Luis Ascorbe
@JasonMing 这是唯一对我有效的方法,我花了近5个小时来寻找解决方案。非常感谢... - Charles Robertson
"私有 API" 是什么意思?有人可以解释一下吗? - Charles Robertson
仅出于兴趣,如果您可以使用KVC,为什么不能编写self.popoverController? - Charles Robertson

4
我已经成功实现了这个功能,而且我认为它不是一个黑客行为。我有一个标准的分割视图iPad应用程序。然后我在我的详细控制器(弹出窗口的所有者)上添加了一个处理解除的方法。
在标准的分割视图结构中,根视图和详细视图控制器都可以通过应用程序委托访问。因此,我将弹出窗口内部的按钮单击绑定到调用一个方法,该方法获取应用程序委托。从那里,我调用详细控制器上的方法来关闭弹出窗口。
下面是在弹出窗口中显示的视图控制器上的方法代码:
- (void) exitView: (id)sender {
    MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];

    [appDelegate.detailViewController exitDrill];
}

那么在详细视图控制器上解除的简单方法是:

- (void) exitDrill {
    if(dtController != nil){
      [dtController dismissPopoverAnimated: YES];
      [dtController release];
    }
}

我喜欢这种能力,因为它给了我一种向用户展示如何退出弹出窗口的方式。虽然在未来版本的应用程序中可能不再需要,但现在,由于这种范例对平台仍然很新,我更愿意让用户以几种不同的方式退出显示,以确保我最大限度地减少他们的沮丧感。


0

正如Ed Marty所写

如果您想通过按按钮来关闭弹出窗口,某个相关的地方应该保留对弹出窗口的引用

这是非常正确的;然而,在显示UIPopoverController时,打开popovercontroller的类已经保留了这个资源。因此,您可以将此类用作Popover Controller的委托类。

为此,您可以执行以下操作,我在我的代码中使用:

在打开popover的类中,这是我的代码:

- (void)showInformationForView:(Booking*)booking frame:(CGRect)rect
{
    BookingDetailsViewController *bookingView = [[BookingDetailsViewController alloc] initWithStyle:UITableViewStyleGrouped booking:booking];
    [bookingView setDelegate:self];

    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:bookingView];

    self.popController = [[UIPopoverController alloc] initWithContentViewController:navController];
    [self.popController setDelegate:self];
    [self.popController setPopoverContentSize:CGSizeMake(320, 320)];

    rect.size.width = 0;

    [self.popController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}

- (void)dismissPopoverAnimated:(BOOL)animated
{
    [self.popController dismissPopoverAnimated:animated];
}

所以我在这里做的是创建一个UINavigationController,并将BookingDetailsViewController设置为其rootViewController。然后我还将当前类添加为此BookingDetailsViewController的代理。
我添加的第二件事是一个名为dismissPopoverAnimated:animated的解散方法。
在我的BookingDetailsViewController.h中,我添加了以下代码:
[...]
@property (nonatomic, strong) id delegate;
[...]

在我的BookingDetailsViewController.m中,我添加了以下代码:

[...]

@synthesize delegate = _delegate;

- (void)viewDidLoad

{
    UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(closeView)];
    [self.navigationItem setRightBarButtonItem:closeButton];

    [super viewDidLoad];
}

- (void)closeView
{
    if ([self.delegate respondsToSelector:@selector(dismissPopoverAnimated:)]) {
        [self.delegate dismissPopoverAnimated:YES];
    }
    else {
        NSLog(@"Cannot close the view, nu such dismiss method");
    }
}

[...]

发生的情况是当 UINavigationController 中的“关闭”按钮被按下时,会调用方法 closeView。该方法检查代理是否响应 dismissPopoverAnimated:animated,如果是,则调用它。如果不响应此方法,则会显示日志消息并什么也不做(因此不会崩溃)。
我使用 ARC 编写了我的代码,因此没有内存管理。
希望这可以帮助你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接