为touchesBegan函数添加计时器:多用户触屏放置UIImage技术求助
嘿,这就来帮你把计时器功能加到你的多用户触屏App里!结合你已经写的代码,我给你梳理清楚实现步骤和完整代码~
实现思路
首先咱们明确核心逻辑:用户点击屏幕后,在点击位置显示对应人物图片,同时启动计时器——这里默认做「3秒后自动隐藏图片」的逻辑;如果用户提前松开手指,也能立刻停止计时器并清理资源。你可以根据需求随时调整计时器的触发行为,比如记录触摸时长、重复执行动作等。
完整代码补充与修改
我把你现有的代码补全,加上计时器相关的变量和逻辑:
import UIKit class YourViewController: UIViewController { var users = 0 @IBOutlet weak var Person_1: UIImageView! @IBOutlet weak var Person_2: UIImageView! @IBOutlet weak var Person_3: UIImageView! @IBOutlet weak var Person_4: UIImageView! @IBOutlet weak var Person_5: UIImageView! var fingers = [String?](repeating: nil, count:5) // 新增:存储每个用户对应的计时器,方便后续取消和管理 var touchTimers: [UITimer?] = Array(repeating: nil, count: 5) override func viewDidLoad() { super.viewDidLoad() // 初始化时隐藏所有人物图片 [Person_1, Person_2, Person_3, Person_4, Person_5].forEach { $0?.isHidden = true } } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesBegan(touches, with: event) for touch in touches { let touchPos = touch.location(in: view) // 找到第一个未被占用的用户位置 guard let freeIndex = fingers.firstIndex(where: { $0 == nil }) else { print("最多支持5个用户同时操作哦") return } // 获取对应位置的人物ImageView let targetPerson = getPersonView(at: freeIndex) // 设置图片位置为点击点 targetPerson.center = touchPos targetPerson.isHidden = false // 先取消该位置之前的计时器(如果有) touchTimers[freeIndex]?.invalidate() // 启动新计时器:3秒后隐藏图片并释放位置 let timer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false) { [weak self] _ in guard let self = self else { return } targetPerson.isHidden = true self.fingers[freeIndex] = nil self.touchTimers[freeIndex] = nil } touchTimers[freeIndex] = timer fingers[freeIndex] = "user_\(freeIndex+1)" // 标记该位置已占用 } } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesEnded(touches, with: event) // 用户松开手指时,停止对应计时器并隐藏图片 for touch in touches { if let usedIndex = fingers.firstIndex(where: { $0 != nil }) { touchTimers[usedIndex]?.invalidate() touchTimers[usedIndex] = nil getPersonView(at: usedIndex).isHidden = true fingers[usedIndex] = nil } } } // 辅助函数:根据索引获取对应的人物ImageView private func getPersonView(at index: Int) -> UIImageView { switch index { case 0: return Person_1 case 1: return Person_2 case 2: return Person_3 case 3: return Person_4 case 4: return Person_5 default: return Person_1 // 兜底,实际不会走到这里 } } }
关键细节说明
- 计时器独立管理:用
touchTimers数组和用户位置一一绑定,确保每个用户的计时器互不干扰,避免出现「一个计时器影响多个用户」的问题。 - 防止内存泄漏:在Timer的闭包里用
[weak self],避免ViewController被计时器强引用导致内存无法释放。 - 触摸事件闭环处理:
touchesBegan负责分配用户、显示图片、启动计时器;touchesEnded负责清理计时器和用户资源,保证逻辑完整。 - 灵活扩展:如果想修改计时器功能,比如记录触摸时长,只需要加一个存储开始时间的数组,在
touchesBegan记录时间,touchesEnded计算时长:// 新增存储开始时间的数组 var touchStartTimes: [Date?] = Array(repeating: nil, count: 5) // 在touchesBegan里添加 touchStartTimes[freeIndex] = Date() // 在touchesEnded里计算 if let startTime = touchStartTimes[usedIndex] { let duration = Date().timeIntervalSince(startTime) print("用户\(usedIndex+1)触摸时长:\(duration)秒") touchStartTimes[usedIndex] = nil }
内容的提问来源于stack exchange,提问作者Dani Kemper
相关产品推荐
相关产品推荐

