如何在没有任何按钮的情况下以编程方式关闭 UIAlertController?

Posted

技术标签:

【中文标题】如何在没有任何按钮的情况下以编程方式关闭 UIAlertController?【英文标题】:How to programmatically dismiss UIAlertController without any buttons? 【发布时间】:2015-08-06 13:29:52 【问题描述】:

我正在展示一个没有任何按钮的 UIAlertViewController,因为它应该只是通知用户上传正在进行中。该应用程序应该将一些文件上传到 Amazon S3(有些事情发生在并行线程上),我担心当我想关闭它时,对警报视图控制器的引用会丢失。

知道什么地方出了问题吗? 我什至不知道如何调试,因为调试区域没有错误?

我有一个类级别的属性:var uploadInProgressAlert = UIAlertController()

我使用此代码在没有按钮的情况下显示我的警报(它有效):

self.uploadInProgressAlert = UIAlertController(title: "Uploading", message: "Please wait.", preferredStyle: .Alert)
self.presentViewController(self.uploadInProgressAlert, animated: true, completion: nil)

此代码用于解除警报(警报不会被解除): self.uploadInProgressAlert.dismissViewControllerAnimated(false, completion: nil)

在此线程中:ios dismiss UIAlertController in response to event 有人谈到“持有参考”。我不知道“保留参考”是什么意思,我认为这可能是问题的根源。

编辑:我把上面的代码放在一个简单的测试应用程序中,它就可以工作了。但是当一些并行线程变得复杂时,我找不到解除警报的方法。

var delay4s = NSTimer()
var delay8s = NSTimer()
var alert = UIAlertController()

func showAlert() 
    if NSClassFromString("UIAlertController") != nil 
        alert = UIAlertController(title: "Uploading", message: "Please wait! \n\n", preferredStyle: UIAlertControllerStyle.Alert)
        self.presentViewController(alert, animated: true, completion: nil)
    


func dismissAlert()
    self.alert.dismissViewControllerAnimated(true, completion: nil)


override func viewDidLoad() 
    super.viewDidLoad()
    delay4s = NSTimer.scheduledTimerWithTimeInterval(4.0, target: self, selector: "showAlert", userInfo: nil, repeats: false)
    delay8s = NSTimer.scheduledTimerWithTimeInterval(8.0, target: self, selector: "dismissAlert", userInfo: nil, repeats: false)

【问题讨论】:

持有引用就是你正在做的——让 alert 成为一个实例变量 持有一个引用正是你通过声明一个类属性uploadInProgressAlert所做的。你确定解雇这条线曾经被叫过吗? 是的,我确定该行被调用了,因为我在该行之前和之后有一些 println()。 【参考方案1】:

通常,父视图控制器负责关闭模态呈现的视图控制器(您的弹出窗口)。在 Objective-C 中,你会在父视图控制器中做这样的事情:

[self dismissViewControllerAnimated:YES completion:nil];

Swift 版本

self.dismissViewControllerAnimated(true, completion: nil)

斯威夫特 3.0:

self.dismiss(animated: true, completion: nil)

【讨论】:

是的,这实际上为我指明了正确的方向。我不得不使用self.dismissViewControllerAnimated(false, completion: nil) 而不是self.uploadInProgressAlert.dismissViewControllerAnimated(false, completion: nil)。但是我不明白为什么它有效,但它有效。 它之所以有效,是因为 @MySpecialPurpose 父视图控制器负责关闭任何呈现的视图控制器 如果父级也是“模态”怎么办? @Daniel 那么如果另一个 VC 先出现怎么办? 即使当前没有显示警报控制器,这样调用是否安全?我已经尝试过了,但它什么也没做(根据需要),但我只是想知道是否有任何意外的副作用。【参考方案2】:

你可以这样做:

nameOfYourAlertController.dismiss(animated: true, completion: nil)

true 将动画消失,false 将突然移除警报

【讨论】:

【参考方案3】:

如果您想发布一个短暂显示然后自行关闭的警报,您可以使用以下方法:

  func postAlert(title: String, message: String) 
    let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
    self.present(alert, animated: true, completion: nil)

    // delays execution of code to dismiss
    DispatchQueue.main.asyncAfter(deadline: .now() + 2.0, execute: 
      alert.dismiss(animated: true, completion: nil)
    )
  

【讨论】:

【参考方案4】:

使用alertController自己的方法销毁自己。

UIAlertController *alertController = [UIAlertController 
alertControllerWithTitle:...];

[alertController dismissViewControllerAnimated:YES completion:nil];

【讨论】:

纯代码答案对社区没有用处。请解释为什么您的代码可以解决问题【参考方案5】:

上面的一切似乎都不起作用,但这对我来说是完美的(xcode 10,swift 5)。享受!

第 1 步: 放置这是您的 viewController 类

    var newQuestionAlert:UIAlertController?

第 2 步: 创建显示警报的函数

  func ShowNewQuestionPopup() 
    if newQuestionAlert == nil 
        newQuestionAlert = UIAlertController(title: "Notice", message: "Next Question Starting", preferredStyle: .alert)
        if let newQuestionAlert = newQuestionAlert 
            newQuestionAlert.addAction(UIAlertAction(title: "OK", style: .default, handler:  action in
                self.newQuestionAlert = nil
                return
            ))
            self.present(newQuestionAlert, animated: true, completion: nil)
         
     
 

第 3 步: 创建关闭警报的函数

func autoDismiss() 
    newQuestionAlert?.dismiss(animated: false, completion: nil)
    newQuestionAlert = nil

第 4 步: 根据需要调用函数

【讨论】:

以上是关于如何在没有任何按钮的情况下以编程方式关闭 UIAlertController?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用命令的情况下以编程方式关闭/重启 linux 机器(运行时)

如何在不使用 Facebook 登录/注销按钮的情况下以编程方式从 Facebook SDK 3.0 注销?

在没有 BHO 的情况下以编程方式确定 IE 窗口当前 URL

如何在不编码窗口状态的情况下以编程方式终止 NSApp?

如何在没有情节提要的情况下以编程方式实例化视图控制器

如何在不制作 IBOutlet 的情况下以编程方式在 Swift 中为 UIView 高度约束设置动画?