在同一 UIView 中多次检测到点击手势
Tap Gesture Detected Multiple Times in the same UIView
目前,我正在尝试将 UITapGestureRecognizer
添加到 UIView
以启动计时器。但是,每当我错误地多次点击 UIView
时,都会识别出多个手势并且计时器 运行 两次,或者比平时快好几倍。
我想确保 UIView
仅识别 1 个定时器动作/1 个点击手势,并且第二次点击将是多余的(稍后我将努力确保第二次点击“停止”定时器)。
我尝试阅读 ,但它并没有完全指导我如何防止第二次点击或根据状态自定义操作,我仍在努力弄清楚,但我卡在这个问题上了。
如果您对我如何解决此问题有任何见解,请提供帮助。
class ActiveExerciseTableViewCell: UITableViewCell, UITextFieldDelegate {
var restTimer = Timer()
var restTimeRemaining: Int = 180
func setUpActiveExerciseUIViewLayout(){
timerLabel.translatesAutoresizingMaskIntoConstraints = false
timerLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
timerLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: (contentView.frame.height-tableviewContentViewTabBarHeight)*0.55).isActive = true
timerLabel.widthAnchor.constraint(equalToConstant: contentView.frame.width * 0.7).isActive = true
timerLabel.heightAnchor.constraint(equalToConstant: 80).isActive = true
timerLabel.font = .boldSystemFont(ofSize: 64)
activeExerciseTimerUIView.translatesAutoresizingMaskIntoConstraints = false
activeExerciseTimerUIView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
activeExerciseTimerUIView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: (contentView.frame.height-tableviewContentViewTabBarHeight)*0.25).isActive = true
activeExerciseTimerUIView.widthAnchor.constraint(equalToConstant: 225).isActive = true
activeExerciseTimerUIView.heightAnchor.constraint(equalToConstant: 225).isActive = true
let timerStartGesture = UITapGestureRecognizer(target: self, action: #selector(playTapped))
timerStartGesture.numberOfTapsRequired = 1
activeExerciseTimerUIView.addGestureRecognizer(timerStartGesture)
activeExerciseTimerUIView.isUserInteractionEnabled = true
}
@objc func playTapped(_ sender: Any) {
restTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(step), userInfo: nil, repeats: true)
}
@IBAction func pauseTapped(_ sender: Any) {
restTimer.invalidate()
}
@IBAction func resetTapped(_ sender: Any) {
restTimer.invalidate()
restTimeRemaining = 180
timerLabel.text = "\(restTimeRemaining)"
}
@objc func step() {
if restTimeRemaining > 0 {
restTimeRemaining -= 1
} else {
restTimer.invalidate()
restTimeRemaining = 180
}
timerLabel.text = prodTimeString(time: TimeInterval(restTimeRemaining))
}
func prodTimeString(time: TimeInterval) -> String {
let Minutes = Int(time) / 60 % 60
let Seconds = Int(time) % 60
return String(format: "%02d:%02d", Minutes, Seconds)
}
}
使用布尔值处理状态变化:
class ActiveExerciseTableViewCell: UITableViewCell, UITextFieldDelegate {
var restTimer = Timer()
var restTimeRemaining: Int = 180
var timerInitiated: Bool = false /// here!
func setUpActiveExerciseUIViewLayout() {
timerLabel.translatesAutoresizingMaskIntoConstraints = false
timerLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
timerLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: (contentView.frame.height-tableviewContentViewTabBarHeight)*0.55).isActive = true
timerLabel.widthAnchor.constraint(equalToConstant: contentView.frame.width * 0.7).isActive = true
timerLabel.heightAnchor.constraint(equalToConstant: 80).isActive = true
timerLabel.font = .boldSystemFont(ofSize: 64)
activeExerciseTimerUIView.translatesAutoresizingMaskIntoConstraints = false
activeExerciseTimerUIView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
activeExerciseTimerUIView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: (contentView.frame.height-tableviewContentViewTabBarHeight)*0.25).isActive = true
activeExerciseTimerUIView.widthAnchor.constraint(equalToConstant: 225).isActive = true
activeExerciseTimerUIView.heightAnchor.constraint(equalToConstant: 225).isActive = true
let timerStartGesture = UITapGestureRecognizer(target: self, action: #selector(playTapped))
timerStartGesture.numberOfTapsRequired = 1
activeExerciseTimerUIView.addGestureRecognizer(timerStartGesture)
activeExerciseTimerUIView.isUserInteractionEnabled = true
}
@objc func playTapped(_ sender: Any) {
if !timerInitiated { /// check here
restTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(step), userInfo: nil, repeats: true)
self.timerInitiated = true
}
}
@IBAction func pauseTapped(_ sender: Any) {
restTimer.invalidate()
}
@IBAction func resetTapped(_ sender: Any) {
restTimer.invalidate()
restTimeRemaining = 180
timerLabel.text = "\(restTimeRemaining)"
}
@objc func step() {
if restTimeRemaining > 0 {
restTimeRemaining -= 1
} else {
restTimer.invalidate()
restTimeRemaining = 180
}
timerLabel.text = prodTimeString(time: TimeInterval(restTimeRemaining))
}
func prodTimeString(time: TimeInterval) -> String {
let Minutes = Int(time) / 60 % 60
let Seconds = Int(time) % 60
return String(format: "%02d:%02d", Minutes, Seconds)
}
}
如果 timerInitiated
布尔值是真,这意味着练习已经开始并且不会再安排任何计时器,除非布尔值被改变。
目前,我正在尝试将 UITapGestureRecognizer
添加到 UIView
以启动计时器。但是,每当我错误地多次点击 UIView
时,都会识别出多个手势并且计时器 运行 两次,或者比平时快好几倍。
我想确保 UIView
仅识别 1 个定时器动作/1 个点击手势,并且第二次点击将是多余的(稍后我将努力确保第二次点击“停止”定时器)。
我尝试阅读
如果您对我如何解决此问题有任何见解,请提供帮助。
class ActiveExerciseTableViewCell: UITableViewCell, UITextFieldDelegate {
var restTimer = Timer()
var restTimeRemaining: Int = 180
func setUpActiveExerciseUIViewLayout(){
timerLabel.translatesAutoresizingMaskIntoConstraints = false
timerLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
timerLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: (contentView.frame.height-tableviewContentViewTabBarHeight)*0.55).isActive = true
timerLabel.widthAnchor.constraint(equalToConstant: contentView.frame.width * 0.7).isActive = true
timerLabel.heightAnchor.constraint(equalToConstant: 80).isActive = true
timerLabel.font = .boldSystemFont(ofSize: 64)
activeExerciseTimerUIView.translatesAutoresizingMaskIntoConstraints = false
activeExerciseTimerUIView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
activeExerciseTimerUIView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: (contentView.frame.height-tableviewContentViewTabBarHeight)*0.25).isActive = true
activeExerciseTimerUIView.widthAnchor.constraint(equalToConstant: 225).isActive = true
activeExerciseTimerUIView.heightAnchor.constraint(equalToConstant: 225).isActive = true
let timerStartGesture = UITapGestureRecognizer(target: self, action: #selector(playTapped))
timerStartGesture.numberOfTapsRequired = 1
activeExerciseTimerUIView.addGestureRecognizer(timerStartGesture)
activeExerciseTimerUIView.isUserInteractionEnabled = true
}
@objc func playTapped(_ sender: Any) {
restTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(step), userInfo: nil, repeats: true)
}
@IBAction func pauseTapped(_ sender: Any) {
restTimer.invalidate()
}
@IBAction func resetTapped(_ sender: Any) {
restTimer.invalidate()
restTimeRemaining = 180
timerLabel.text = "\(restTimeRemaining)"
}
@objc func step() {
if restTimeRemaining > 0 {
restTimeRemaining -= 1
} else {
restTimer.invalidate()
restTimeRemaining = 180
}
timerLabel.text = prodTimeString(time: TimeInterval(restTimeRemaining))
}
func prodTimeString(time: TimeInterval) -> String {
let Minutes = Int(time) / 60 % 60
let Seconds = Int(time) % 60
return String(format: "%02d:%02d", Minutes, Seconds)
}
}
使用布尔值处理状态变化:
class ActiveExerciseTableViewCell: UITableViewCell, UITextFieldDelegate {
var restTimer = Timer()
var restTimeRemaining: Int = 180
var timerInitiated: Bool = false /// here!
func setUpActiveExerciseUIViewLayout() {
timerLabel.translatesAutoresizingMaskIntoConstraints = false
timerLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
timerLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: (contentView.frame.height-tableviewContentViewTabBarHeight)*0.55).isActive = true
timerLabel.widthAnchor.constraint(equalToConstant: contentView.frame.width * 0.7).isActive = true
timerLabel.heightAnchor.constraint(equalToConstant: 80).isActive = true
timerLabel.font = .boldSystemFont(ofSize: 64)
activeExerciseTimerUIView.translatesAutoresizingMaskIntoConstraints = false
activeExerciseTimerUIView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
activeExerciseTimerUIView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: (contentView.frame.height-tableviewContentViewTabBarHeight)*0.25).isActive = true
activeExerciseTimerUIView.widthAnchor.constraint(equalToConstant: 225).isActive = true
activeExerciseTimerUIView.heightAnchor.constraint(equalToConstant: 225).isActive = true
let timerStartGesture = UITapGestureRecognizer(target: self, action: #selector(playTapped))
timerStartGesture.numberOfTapsRequired = 1
activeExerciseTimerUIView.addGestureRecognizer(timerStartGesture)
activeExerciseTimerUIView.isUserInteractionEnabled = true
}
@objc func playTapped(_ sender: Any) {
if !timerInitiated { /// check here
restTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(step), userInfo: nil, repeats: true)
self.timerInitiated = true
}
}
@IBAction func pauseTapped(_ sender: Any) {
restTimer.invalidate()
}
@IBAction func resetTapped(_ sender: Any) {
restTimer.invalidate()
restTimeRemaining = 180
timerLabel.text = "\(restTimeRemaining)"
}
@objc func step() {
if restTimeRemaining > 0 {
restTimeRemaining -= 1
} else {
restTimer.invalidate()
restTimeRemaining = 180
}
timerLabel.text = prodTimeString(time: TimeInterval(restTimeRemaining))
}
func prodTimeString(time: TimeInterval) -> String {
let Minutes = Int(time) / 60 % 60
let Seconds = Int(time) % 60
return String(format: "%02d:%02d", Minutes, Seconds)
}
}
如果 timerInitiated
布尔值是真,这意味着练习已经开始并且不会再安排任何计时器,除非布尔值被改变。