未调用 UIAlertAction 处理程序

Posted

技术标签:

【中文标题】未调用 UIAlertAction 处理程序【英文标题】:UIAlertAction handler is not called 【发布时间】:2015-07-29 09:38:01 【问题描述】:

我有一个 UITableView 并且在委托(视图控制器)中,我已经实现了该功能

    tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)

然后我测试编辑风格

    if editingStyle == UITableViewCellEditingStyle.Delete 
        // do deleting stuff here
    

作为删除的一部分,我要求用户确认,如果他们选择“是”,与该行相关的项目将被删除,如果他们选择“否”,我会重置编辑样式。

  var alert = UIAlertController(title: "Delete Item", message: "Are you sure you want to delete the selected item?", preferredStyle: UIAlertControllerStyle.Alert)

  //delete
  alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.Destructive, handler:  (action: UIAlertAction!) -> Void in
      println("Yes action was selected")
      //delete my object and remove from the table
  ))

  //cancel
  alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler:  (action: UIAlertAction!) -> Void in
      //reset editing
      println("Cancel action was selected")
      self.tableView.setEditing(false, animated: true)
  ))

  if self.presentedViewController == nil 
      presentViewController(alert, animated: true, completion: nil)
  

我似乎遇到的问题是两个完成处理程序都没有被调用。我在其他地方使用过这种格式,没有任何问题。

警报会显示标题、消息以及“取消”和“是”按钮。如果我点击任何一个,都不会发生任何事情。警报被解除,并且 println 语句没有控制台输出,并且肯定没有其他任何事情发生。 “是”没有执行我的删除代码,“取消”没有调用编辑重置。

我在应用程序中的其他表视图上也有相同的设置,它们按预期工作。

这是在一个视图控制器中,该视图控制器已从另一个视图控制器模态呈现(如果有任何影响)。我没有收到关于正在进行的任何其他演示的任何错误(因此if self.presentedViewController == nil 块)。

我显然在某个地方出错了,但目前我只是看不出在哪里。有什么想法吗?

ios 版本在 8.4 中使用。目标是 iPad。

【问题讨论】:

顺便提一下,删除的东西是有效的。如果我不费心尝试提示,我的删除代码将按预期工作。我只是看不出我在 UIAlertController 和 UIAlertActions 上做错了什么。 我使用你的代码,它运行良好。 是的,它在我的应用程序的其他区域也可以完美运行 - 因此对于为什么它在这种情况下不起作用感到困惑 【参考方案1】:

我有同样的问题,我发现我覆盖了解除函数:

override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) 
    super.dismiss(animated: true, completion: nil)

当您传递 nil 时,UIAlertController 正在使用完成块传递数据,该操作根本不会调用。

当你重写dismiss func时你需要传递完成参数

override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) 
    super.dismiss(animated: true, completion: completion)

希望能帮到你

【讨论】:

你我的男人!确保你也为 swizzled 方法调用完成,以防你在那里运行自己的块【参考方案2】:

检查您的ViewController 是导航的childViewController。如果导航覆盖:

(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^) (void))completion;

您一定要致电super dismissViewControllerAnimated:flag completion:completion

并确保参数completion不能通过nilUIAlertController 会调用这个方法(我也很困惑)。 我注销来电者是UIAlertController _dismissAnimated:triggeringAction:triggeredByPopoverDimmingView:(又是一头雾水)。

它对我有用。我希望它也适用于你。

【讨论】:

这使我免于拔出我的发根。谢谢!【参考方案3】:

您可以检查这是否有效

    alert.addAction(UIAlertAction(title: "cancel", style: UIAlertActionStyle.Cancel, handler:  action in
        switch action.style
        case .Default:
            println("default")

        case .Cancel:
            println("cancel")

        case .Destructive:
            println("destructive")
        
    ))

【讨论】:

不,这行不通。处理程序没有被调用。警报出现,“取消”动作出现在警报上。点击取消 - 解除警报,不调用处理程序。同上。 所以“取消”没有打印?处理程序内部也没有调用您的断点? 这正是正在发生的事情。我不明白为什么不调用处理程序。目前,我只是在不提示用户的情况下执行删除。我就是想不通。我在其他地方使用相同的代码来处理同一应用程序中的类似提示,即使是在其他表视图中删除也是如此。我只是看不出这里有什么不同。我什至从其他区域粘贴了相同的代码,只是更改了主要警报消息的文本,处理程序中只有一个 println 语句。处理程序只是没有被调用。【参考方案4】:

这个问题比较老了,但我今天遇到了同样的麻烦。

关键是你使用的是 iPad,所以你必须在弹出窗口中展示它

if UIDevice.current.userInterfaceIdiom == .pad
  alert.modalPresentationStyle = .popover
  let pp = ac.popoverPresentationController
  pp?.sourceView = sender as? UIView // or pp?.sourceRect = <some rect...>
  present(alert, animated: true, completion: )
else
  present(alert, animated: true, completion: )

注意:这是swift3

【讨论】:

应用程序中的其他警报都不需要弹出框

以上是关于未调用 UIAlertAction 处理程序的主要内容,如果未能解决你的问题,请参考以下文章

如何执行 UIAlertAction 的处理程序?

制作 UIAlertAction 处理程序的正确方法

从 UIAlertController 中添加对函数的调用 [重复]

UIAlertAction 处理程序延迟后运行

在 UIAlertAction 处理程序中更新 UI

UIAlertAction 的处理程序有点太晚了——我怎样才能让它立即生效?