Swift中圆形视图Tap Gesture无效,如何实现点击计分?
问题:圆形Tap Gesture无法触发,请求修复并实现计分功能
我正在开发一款单页游戏,玩家点击圆形即可提升分数等级。游戏已接近完成,但圆形上的Tap Gesture无法触发。我尝试了以下代码但没有效果,请帮忙检查代码并告知如何让Tap Gesture生效并实现计分功能,若我有错误请指正。
import UIKit import AVFoundation class Demogame: UIViewController { @IBOutlet weak var scoreLabel: UILabel! var score = 0 var isGameOver = false override func viewDidLoad() { super.viewDidLoad() startGame() } func startGame() { score = 0 scoreLabel.text = "Score: \(score)" isGameOver = false // 创建生成圆形的计时器 Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { timer in if !self.isGameOver { self.spawnCircle() } else { timer.invalidate() } } } func spawnCircle() { let circleSize = CGSize(width: 50, height: 50) let circleView = UIView(frame: CGRect(origin: CGPoint(x: CGFloat.random(in: 50...view.frame.width - circleSize.width - 50), y: CGFloat.random(in: 100...view.frame.height - circleSize.height - 50)), size: circleSize)) circleView.backgroundColor = UIColor.random() circleView.layer.cornerRadius = circleSize.width / 2 view.addSubview(circleView) // 为每个圆形添加点击手势识别器 let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:))) circleView.addGestureRecognizer(tapGesture) // 圆形出现和消失的动画 UIView.animate(withDuration: 3.0, animations: { circleView.alpha = 0.0 }) { (completed) in if completed { circleView.removeFromSuperview() } } } @objc func handleTap(_ sender: UITapGestureRecognizer) { if isGameOver { return } if let tappedView = sender.view { tappedView.removeFromSuperview() score += 1 scoreLabel.text = "Score: \(score)" } } } extension UIColor { static func random() -> UIColor { return UIColor( red: CGFloat.random(in: 0.0...1.0), green: CGFloat.random(in: 0.0...1.0), blue: CGFloat.random(in: 0.0...1.0), alpha: 1.0 ) } }
问题分析与修复方案
1. 核心问题:UIView默认关闭用户交互
你的代码中Tap Gesture无法触发的根本原因是:UIView的isUserInteractionEnabled属性默认值为false,这会导致所有手势识别器无法响应。
修复方法:在spawnCircle()方法中创建circleView后,添加一行代码开启交互:
circleView.isUserInteractionEnabled = true
2. 优化动画的交互体验
当前动画直接将圆形的alpha从默认值(0)变到0,会导致圆形刚生成就处于透明状态,用户难以点击。可以调整为:
// 先让圆形完全显示 circleView.alpha = 1.0 // 再执行消失动画 UIView.animate(withDuration: 3.0, animations: { circleView.alpha = 0.0 }) { (completed) in if completed { circleView.removeFromSuperview() } }
这样能保证圆形在可见的3秒内都能正常响应点击。
3. 可选优化:避免计时器循环引用
当前的闭包计时器存在潜在的循环引用风险,建议将计时器保存为实例变量并使用弱引用:
// 新增实例变量 var spawnTimer: Timer? func startGame() { score = 0 scoreLabel.text = "Score: \(score)" isGameOver = false // 先取消之前的计时器,避免重复创建 spawnTimer?.invalidate() spawnTimer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { [weak self] timer in guard let self = self, !self.isGameOver else { timer.invalidate() return } self.spawnCircle() } }
4. 计分功能验证
修复上述问题后,handleTap(_:)方法会正常触发,每次点击圆形时:
- 圆形会被移除
- 分数自动+1
- 分数标签会实时更新显示
内容的提问来源于stack exchange,提问作者Sham Dhiman
相关产品推荐
相关产品推荐

