J'ai créé un chronomètre à l'aide de la minuterie dans cette application et j'ai ajouté un bouton de démarrage et d'arrêt pour mettre en pause et lire la même chose. Lorsque le bouton-poussoir est enfoncé, il est envoyé à une fonction qui invalide la minuterie et il doit s'arrêter. Mais étrangement assez lorsque vous appuyez sur le bouton d'arrêt, au lieu d'arrêter la minuterie accélère d'une manière ou d'une autre Je n'ai pas changé l'intervalle de temps sauf une fois juste en le déclarant.
J'ai essayé de désactiver le bouton de démarrage une fois qu'il est enfoncé et même de le cacher. a également essayé de changer l'intervalle de temps mais rien ne fonctionne. plus j'appuie sur le bouton start stop, plus il accélère et commence à aller beaucoup plus vite que l'intervalle de temps mentionné.
startButton.frame = CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1) startButton.setTitle("Start Timer", for: .normal) self.view.addSubview(startButton) startButton.setTitleColor(.white , for: .normal) startButton.backgroundColor = .red startButton.addTarget(self, action: #selector(playButton(_:)), for: .allTouchEvents) stopButton.frame = CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1) stopButton.setTitle("Stop Timer", for: .normal) stopButton.setTitleColor(.white , for: .normal) stopButton.backgroundColor = .red stopButton.addTarget(self, action: #selector(pauseButton(_:)), for: .allTouchEvents) @objc func playButton(_ sender : Any) { timer = Timer.scheduledTimer(timeInterval: 1, target: self , selector: #selector(updateTimer), userInfo: nil, repeats: true) startButton.isEnabled = false stopButton.isEnabled = true isRunning = true self.view.addSubview(stopButton) startButton.isHidden = true stopButton.isHidden = false } @objc func pauseButton(_ sender: Any) { self.view.addSubview(startButton) timer.invalidate() stopButton.isHidden = true startButton.isHidden = false startButton.isEnabled = true stopButton.isEnabled = false isRunning = false } @objc func updateTimer(_ sender : Any) { counter += 0.1 titleLabel.text = String(format: "%.1f", counter) }
3 Réponses :
Essayez d'ajouter les deux boutons en même temps en masquant le bouton d'arrêt et masquez et affichez simplement les boutons en cliquant sur le bouton. Votre méthode de bouton de lecture s'exécute à chaque fois, lorsque vous essayez d'arrêter le minuteur
J'ai ajouté un bouton d'arrêt dans ses propriétés comme le bouton de démarrage et supprimé toutes les lignes de code de masquage du bouton de démarrage, mais rien n'a changé. Cela n'explique pas non plus pourquoi la minuterie s'accélérerait et commencerait à aller de plus en plus vite à chaque clic d'arrêt
Cela est dû au fait que votre méthode playButton est appelée encore et encore. vérifiez-le en plaçant un point d'arrêt sur cette fonction
ok merci beaucoup cela a fonctionné et j'ai passé des heures mais je n'ai pas pu voir l'erreur
Je les ai utilisés mais je n'ai pas remarqué qu'ils étaient arrêtés deux fois, cela semblait être un décalage dans mon PC, mais je ne sais toujours pas pourquoi cela accélérerait même s'il était appelé encore et encore puisque la définition initiale de l'intervalle ne change jamais
C'est parce que chaque fois que la méthode du bouton de lecture est appelée, un nouveau minuteur séparé est planifié, ce qui provoque l'appel de la méthode updateTimer séparément. Ainsi, chaque fois que cela se produit, la valeur du compteur augmente
Autant que je sache, vous avez 2 erreurs.
Le premier est mentionné par l'autre réponse. Il est vrai que vous ne devriez pas toujours ajouter un nouvel UIButton et utiliser simplement la propriété hide / unhide pour chaque bouton.
La deuxième erreur concerne la façon dont vous ajoutez une cible. Vous utilisez .allTouchEvents, mais vous pourriez avoir l'intention d'utiliser .touchUpInside comme état de contrôle.
Veuillez consulter le code corrigé ci-dessous pour votre référence:
import UIKit class ViewController: UIViewController { @IBOutlet weak var titleLabel: UILabel! var startButton: UIButton! var stopButton: UIButton! var timer: Timer! var counter: Double = 0.0 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. startButton = UIButton(frame: CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1)) startButton.setTitle("Start Timer", for: .normal) startButton.setTitleColor(.white , for: .normal) startButton.backgroundColor = .red startButton.addTarget(self, action: #selector(playButton(_:)), for: .touchUpInside) self.view.addSubview(startButton) self.startButton.isHidden = false stopButton = UIButton(frame: CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1)) stopButton.setTitle("Stop Timer", for: .normal) stopButton.setTitleColor(.white , for: .normal) stopButton.backgroundColor = .red stopButton.addTarget(self, action: #selector(pauseButton(_:)), for: .touchUpInside) self.view.addSubview(stopButton) self.stopButton.isHidden = true } @objc func playButton(_ sender : Any) { timer = Timer.scheduledTimer(timeInterval: 1, target: self , selector: #selector(updateTimer), userInfo: nil, repeats: true) startButton.isEnabled = false stopButton.isEnabled = true startButton.isHidden = true stopButton.isHidden = false } @objc func pauseButton(_ sender: Any) { timer.invalidate() stopButton.isHidden = true startButton.isHidden = false startButton.isEnabled = true stopButton.isEnabled = false } @objc func updateTimer(_ sender : Any) { counter += 0.1 titleLabel.text = String(format: "%.1f", counter) } }
p>
merci pour une réponse aussi détaillée et précise, j'aurais aimé pouvoir remarquer au lieu de perdre des heures, apprécier l'effort
Vous avez déjà 2 bonnes réponses, mais je vais ajouter mon 2p car je pense que les prémisses sur lesquelles vous avez commencé ne sont pas correctes.
Votre plus grande erreur est d'avoir 2 boutons en premier lieu. Vous n'auriez pas eu le problème si vous n'aviez qu'un seul bouton et que vous l'aviez stylé au besoin.
class MyTest { let magicButton = UIButton() let timer: Timer? override viewDidLoad() { super.viewDidLoad() // Setup Button magicButton.addTarget(self, action: #selector(buttonPress(_:)), for: .allTouchEvents) magicButton.setTitleColor(.white , for: .normal) magicButton.frame = yourFrame view.addSubview(magicButton) customiseButton() } @objc private func buttonPress() { if timer == nil { timer = Timer.scheduledTimer(timeInterval: 1, target: self , selector: #selector(updateTimer), userInfo: nil, repeats: true) } else { timer.invalidate() } customiseButton() } private func customiseButton() { let isStartButton = timer == nil let buttonTitle = isStartButton ? "Start" : "Stop" let buttonBackgroundColor: UIColor = isStartButton ? .green : .red magicButton.setTitle(buttonTitle, for: .normal) magicButton.backgroundColor = buttonBackgroundColor } } // add updateTimer function too
De cette façon, vous avez moins de code à maintenir et aucun conflit entre les éléments cachés montré, donc moins de choses qui pourraient mal tourner. La magie se produit dans la méthode buttonPress où si un minuteur est démarré, vous l'arrêtez, sinon vous en démarrez un, suivi d'une mise à jour rapide de l'interface utilisateur du bouton.