web-dev-qa-db-ja.com

Swiftで、3秒後に消えるか、ユーザーがすぐにキャンセルできるポップアップメッセージを表示するにはどうすればよいですか?

私のSwiftアプリには、ボタンが1つある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")
    })

}

それはうまくいきますが、私はいくつかの改善を紹介したいと思いました。このポップアップをすぐにキャンセルして、コンソールにメッセージが表示されないようにするボタンを追加したかったのです。そのようなポップアップをユーザーに表示する方法はありますか?また、このポップアップメッセージに、ポップアップが消えるまでの残り時間を示す秒数が不足しているカウンターを表示する方法はありますか?

7
user3766930

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)")
    }     
}
8
Paulw11

誰かがそれを必要とする場合に備えて、これは@ 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)")
    }
}
1
Dknacht

これがあなたの質問に直接答えないことは知っていますが、 MBProgressHUDSCLAlertView の使用を検討しましたか?どちらも、設定した時間が経過すると消えるアラートを表示できる機能を備えています。 SCLAlertViewを使用すると、MBProgressHUDではキャンセルできないのに対し、ユーザーはすぐにキャンセルできます。これらの実装方法についてさらに情報が必要な場合は、私に知らせてください。情報を追加できます。

0
Dan Levy