第二次单击 UITableView 时应用程序崩溃

App crashes when UITableView clicked second time

MyVC* bottle = [[MyVC alloc] initWithDelegate:self];
bottle.title = @"bottle";

if ( water == nil )
    water = [[UIPopoverController alloc] initWithContentViewController:bottle];
else
    water.contentViewController = bottle;

这段代码运行一次....当我再次点击 UITableViewCell 我的应用程序崩溃了.. 我想不通为什么??

错误

 -[UIPopoverController setContentViewController:animated:] can only be called after the popover has been presented.'

注意 当将我的代码更改为以下时,它会起作用:

MyVC* bottle = [[MyVC alloc] initWithDelegate:self];
bottle.title = @"bottle";

if ( water == nil )
    water = [[UIPopoverController alloc] initWithContentViewController:bottle];
else
    water = [[UIPopoverController alloc] initWithContentViewController:bottle];

但是我使用内存,因为双重分配是 present.How 我可以解决这个问题吗

如果你想推送然后试试这个

MyVC *Newpage = [[MyVC alloc] initWithNibName:@"MyVC" bundle:nil];
    [self.navigationController pushViewController:Newpage animated:YES];

如果你也想从这个页面返回即弹出然后使用这个 您正在使用错误的代码。

[self.navigationController popViewControllerAnimated:YES];

您混淆了 UIPopoverController 的初始化、表示和内容修改。

可以将弹出窗口存储在实例变量上,以避免每次都重新创建它。如果 "water" 已经存在,则将 contentViewController 设置为 "Bottle" 的新实例也不会造成任何问题。

但是您的错误消息说明了一切:-[UIPopoverController setContentViewController:animated:]:您正在尝试使用 动画 更改弹出窗口的内容。这意味着,您的弹出框必须已经呈现(即可见)。为此,请在 更改其内容之前使用以 presentPopoverFrom... 开头的两种方法之一。

换句话说,只有在弹出窗口出现后,您才能为内容的变化设置动画。另请注意,当您的弹出窗口尚未呈现/可见时,为更改设置动画是没有意义的。为此使用 setter .contentViewController =(或非动画方法)。

关于您的 edit/note 的注释:在 if/else 子句的两个分支中编写相同的分配是没有意义的。而且它不会导致系统使用两倍的内存。因为当编译器看到第二行 ("else"...) 时,它首先释放 popovercontroller 的现有实例,然后再分配新实例并使 "water" 实例变量指向它。

隐藏弹出视图时出现问题。检查是否显示正确。

if (popover == nil) {

        popover = [[UIPopoverController alloc] initWithContentViewController: MYVC]; 
        popover.delegate = self;

        [self.tablesPopoverController presentPopoverFromBarButtonItem:sender 
            permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}

使用委托方法检查弹出窗口是否可见。

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
    // do something now that it's been dismissed
}