如何在 Swift 中显示一条弹出消息,该消息在 3 秒后消失或可以由用户立即取消?

Posted

技术标签:

【中文标题】如何在 Swift 中显示一条弹出消息,该消息在 3 秒后消失或可以由用户立即取消?【英文标题】:How can I display a popup message in Swift that disappears after 3 seconds or can be cancelled by user immediatelly? 【发布时间】:2016-04-19 19:16:41 【问题描述】:

在我的 swift 应用程序中,我有一个带有单个按钮的 UIViewController。

此按钮调用一个函数,该函数调用一个 3 秒后消失的弹出窗口。此外,在那之后,它会向控制台打印一条消息。该函数的代码如下:

func showAlertMsg(title: String, message: String)


    let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
    self.presentViewController(alertController, animated: true, completion: nil)
    let delay = 3.0 * Double(NSEC_PER_SEC)
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
    dispatch_after(time, dispatch_get_main_queue(), 
        alertController.dismissViewControllerAnimated(true, completion: nil)
    print("popup disappeared")
    )


这很好,但我想介绍一些改进。我想在那里添加一个按钮,该按钮将立即取消此弹出窗口,然后避免在控制台中显示该消息。有没有办法向用户显示这样的弹出窗口?另外 - 有没有办法在这个弹出消息中显示秒数用完的计数器,显示在弹出窗口消失之前还剩多少时间?

【问题讨论】:

这是我在 Objectice C ***.com/questions/36048240/… 中写的类似答案。本质上,您需要使用 NSTimer 倒计时并在所需时间后关闭警报 这看起来很有希望,我不得不承认 :) 你有没有机会在 swift 中有一个 smilar 代码?我(还)不熟悉 obj-c :| 【参考方案1】:

您可以使用NSTimer 来减少计数器,更新警报视图并在计数器达到 0 时关闭警报视图。此代码改编自我的Objective-C answer

class ViewController: UIViewController 

    var alertController: UIAlertController?
    var alertTimer: NSTimer?
    var remainingTime = 0
    var baseMessage: String?

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    

    override func viewDidAppear(animated: Bool) 
        super.viewDidAppear(animated)         
        self.showAlertMsg("Test Alert", message: "This will disappear in ", time: 5)
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    func showAlertMsg(title: String, message: String, time: Int) 

        guard (self.alertController == nil) else 
            print("Alert already displayed")
            return
        

        self.baseMessage = message
        self.remainingTime = time

        self.alertController = UIAlertController(title: title, message: self.alertMessage(), preferredStyle: .Alert)

        let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel)  (action) in
            print("Alert was cancelled")
            self.alertController=nil;
            self.alertTimer?.invalidate()
            self.alertTimer=nil
        

        self.alertController!.addAction(cancelAction)

        self.alertTimer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(ViewController.countDown), userInfo: nil, repeats: true)       

        self.presentViewController(self.alertController!, animated: true, completion: nil)     
    

    func countDown() 

        self.remainingTime -= 1
        if (self.remainingTime < 0) 
            self.alertTimer?.invalidate()
            self.alertTimer = nil
            self.alertController!.dismissViewControllerAnimated(true, completion: 
                self.alertController = nil
            )
         else 
            self.alertController!.message = self.alertMessage()
        

    

    func alertMessage() -> String 
        var message=""
        if let baseMessage=self.baseMessage 
            message=baseMessage+" "
        
        return(message+"\(self.remainingTime)")
         

【讨论】:

这里是更新的 Swift 3 代码的链接:gist.github.com/anonymous/aadd8e56f2049062c68458c477c28a34【参考方案2】:

以防万一有人需要,这是@Paulw11 解决方案的 Swift 4 版本

import UIKit

class ViewController: UIViewController 

    var alertController: UIAlertController?
    var alertTimer: Timer?
    var remainingTime = 0
    var baseMessage: String?

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    

    override func viewDidAppear(_ animated: Bool) 
        super.viewDidAppear(animated)
        self.showAlertMsg(title: "Test Alert", message: "This will disappear in ", time: 5)
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    func showAlertMsg(title: String, message: String, time: Int) 

        guard (self.alertController == nil) else 
            print("Alert already displayed")
            return
        

        self.baseMessage = message
        self.remainingTime = time

        self.alertController = UIAlertController(title: title, message: self.alertMessage(), preferredStyle: .alert)

        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)  (action) in
            print("Alert was cancelled")
            self.alertController=nil;
            self.alertTimer?.invalidate()
            self.alertTimer=nil
        

        self.alertController!.addAction(cancelAction)

        self.alertTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(ViewController.countDown), userInfo: nil, repeats: true)

        self.present(self.alertController!, animated: true, completion: nil)
    

    @objc func countDown() 

        self.remainingTime -= 1
        if (self.remainingTime < 0) 
            self.alertTimer?.invalidate()
            self.alertTimer = nil
            self.alertController!.dismiss(animated: true, completion: 
                self.alertController = nil
            )
         else 
            self.alertController!.message = self.alertMessage()
        

    

    func alertMessage() -> String 
        var message=""
        if let baseMessage=self.baseMessage 
            message=baseMessage+" "
        
        return(message+"\(self.remainingTime)")
    

【讨论】:

【参考方案3】:

我知道这不能直接回答您的问题,但您是否考虑过使用MBProgressHUDSCLAlertView?它们都提供允许您显示在设定的时间后消失的警报的功能。 SCLAlertView 允许用户立即取消,而 MBProgressHUD 不允许。如果您想了解有关如何实施这些的更多信息,请告诉我,以便我添加更多信息!

【讨论】:

嘿@DanL,谢谢,SCLAlertView 看起来很有趣!但是 - 有没有办法显示在弹出窗口关闭之前还剩多少秒的计数器? 我不认为它内置在 SCLAlertView 中,但我看不出有什么理由不能创建一个 NSTimer 来显示给用户。如果您不知道如何创建倒数计时器,我会在网上快速查找倒数计时器。然后,当 SCLAlertView 出现时,您将触发计时器。请注意,如果您将警报设置为三秒,则计时器可能只会倒计时两秒或两秒半,因为加载需要一点时间。我只想玩弄计时器以使其正常工作。

以上是关于如何在 Swift 中显示一条弹出消息,该消息在 3 秒后消失或可以由用户立即取消?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3 中未调用 ViewForAnnotation

如何弹出“蜂窝数据已关闭”警告信息?

在 Google Colab 上执行任何单元格时出现浏览器弹出消息错误

Swift UIAlertController 显示自定义消息

使用 Swift 在 macOS 上显示 Unobtrusive 消息

如何弹出视图控制器和触发功能