仅在按下另一个按钮后才调用UIAlert动作处理程序?

时间:2018-07-15 18:37:40

标签: ios swift

我有一个看起来像这样的函数:

@IBAction func showAlert(){

//Some irrelevant code

let alert = UIAlertController(title: "Some Title", message: "Some Message", preferredStyle: .alert)

let action = UIAlertAction(title: "Close this alert", style: .default, handler: {
    action in
        self.startNewRound()
    })


alert.addAction(action)

present(alert, animated: true, completion: nil)

}

这里是updateLabels()

updateLabels() { 
targetLabel.text = String(targetValue)
scoreLabel.text = String(score)
roundLabel.text = String(round)

以下是一些全局变量:

var currentValue: Int = 0
@IBOutlet weak var targetLabel: UILabel!
var targetValue: Int = 0
@IBOutlet weak var scoreLabel: UILabel!
@IBOutlet weak var roundLabel: UILabel!
var round: Int = 0

这是startNewRound():

func startNewRound() {
targetValue = Int(arc4random_uniform(100)) + 1
currentValue = 50
slider.value = Float(currentValue)
round += 1
updateLabels()
} 

这个想法是,只要按下我的主视图控制器中的某个按钮,然后弹出警报,就会调用此函数。用户关闭警报后,将调用startNewRound()

但是,使用此当前代码,即使用户关闭警报时调用了startNewRound(),而startNewRound()依次调用了updateLabels()会更改某些标签的文本值,在用户按下任何其他按钮之前,标签上的更改是可见的。我已经确认startNewRound()updateLabels()中的行(更改标签值的代码行之后)均正确运行。我所有的标签都正确连接到了视图控制器中作为插座。

编辑:在几台不同的计算机上运行该程序后,我确认我的代码没有问题。我最初运行项目的计算机运行在安装缓慢的虚拟机上,运行速度非常慢。在其他计算机上运行时,代码运行良好。

2 个答案:

答案 0 :(得分:1)

无法复制。我使用以下代码创建了一个测试项目:

class ViewController: UIViewController {
    @IBAction func showAlert(){
        let alert = UIAlertController(title: "Some Title", message: "Some Message", preferredStyle: .alert)
        let action = UIAlertAction(title: "Close this alert", style: .default, handler: {
            action in
            self.startNewRound()
        })
        alert.addAction(action)
        present(alert, animated: true, completion: nil)
    }
    func startNewRound() {
        print("start new round")
    }
}

我在IBAction上附加了一个按钮,然后运行该项目并点击该按钮。警报出现。我点击了“关闭此警报”。单词“开始新一轮”立即出现在控制台中。无需“先按其他按钮”。

您可以通过执行我的操作轻松确认这一点。

因此,如果您确实具有所描述的行为,则是由于某些原因完全超出了您显示的代码。


为回应您的评论,我更改了代码以更改界面中的一些标签:

class ViewController: UIViewController {
    @IBOutlet weak var label1: UILabel!
    @IBOutlet weak var label2: UILabel!
    @IBOutlet weak var label3: UILabel!
    @IBAction func performButton(_ sender: Any) {
        self.showAlert()
    }
    func showAlert(){
        let alert = UIAlertController(title: "Some Title", message: "Some Message", preferredStyle: .alert)
        let action = UIAlertAction(title: "Close this alert", style: .default, handler: {
            action in
            self.startNewRound()
        })
        alert.addAction(action)
        present(alert, animated: true, completion: nil)
    }
    func startNewRound() {
        self.label1.text = "hey"
        self.label2.text = "ha"
        self.label3.text = "ho"
    }
}

我点击了按钮,警报出现了,我关闭了它,并且标签文本全部更改了。

答案 1 :(得分:0)

如果您希望在显示警报视图后直接调用self.startNewRound(),则可以在显示它的completion中对其进行调用:

present(alert, animated: true) {
    self.startNewRound()
}

和-显然-,将其从动作处理程序中删除。 请紧记completion闭包在演示文稿完成后执行,这意味着它会在 甚至点击按钮之前执行。