ios - ios:在点击collectionview单元格或tableview单元格时禁用第二个触摸事件
问题描述
我有一个带有 CollectionView 的 ViewController,它加载了 ViewController 中提出的问题的四个可能答案。当用户选择一个项目时,会调用 collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) ,其中问题会随着答案数组(始终为 4)而变化,然后调用 collectionView.reloadData 以重绘新问题并可能的答案。
一切正常,除了用户连续快速点击一个项目 2 次。在这种情况下,第一个选择记录了答案,然后 collectionview 再次点击(好像用户再次点击了下一个问题)并因此回答了另一个问题。
如果可能的话,我想做的是: 1. 在第一次触摸时禁用触摸事件(在重新加载新问题时) 2. 在 collectionView 的 reloadData 完成加载后重新启用触摸事件。这是我使用从该线程获取的自定义集合视图类解决的另一个问题如何判断 UITableView 何时完成 ReloadData?
我尝试使用以下方法禁用触摸事件:view.userInteractionEnabled = false/true 和 UIApplication.shared.beginIgnoringInteractionEvents() 和 UIApplication.shared.endIgnoringInteractionEvents(),但没有成功。
这是我迄今为止尝试过的:
func loadNewQuestion {
//UIApplication.shared.beginIgnoringInteractionEvents()
//self.view.isUserInteractionEnabled = false
//change the question, answer, and array of possible answers
answers = answers.shuffled() //simply shuffle the answers
//pick a random answer
let number = Int.random(in: 0 ... 3)
answer = answers[number] //shuffle again and take first value
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if stillAnswering {
print("still answering, so skipping touch events")
return
}
stillAnswering = true
print("not answering")
let a = answers[indexPath.row]
if a.descript.lowercased() == questionAnswer.descript.lowercased() //questionAnswer is the correct answer to the question {
self.loadNewQuestion()
self.collectionView.reloadData(onComplete: {
//UIApplication.shared.endIgnoringInteractionEvents()
//self.view.isUserInteractionEnabled = true
stillAnswering = false
})
} else {
//warn about wrong answer
stillAnswering = false
}
}
我已经标记了objective-c和swift,因为我不介意用于解决方案的语言,而且我相信uitableview和uicollectionview的解决方案/问题是相似的。
任何提示?
解决方案
我终于设法解决了这个问题。解决它的技巧是将 reloadData() 放在一个调度异步块中。这是最终的代码。
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if UIApplication.shared.isIgnoringInteractionEvents {
return //for extra safety
}
UIApplication.shared.beginIgnoringInteractionEvents()
let a = answers[indexPath.row]
if a.descript.lowercased() == questionAnswer.descript.lowercased() //questionAnswer is the correct answer to the question {
self.loadNewQuestion()
DispatchQueue.main.async(execute: {
self.collectionView.reloadData(onComplete: {
UIApplication.shared.endIgnoringInteractionEvents()
})
})
} else {
//warn about wrong answer
DispatchQueue.main.async(execute: {
self.collectionView.reloadData(onComplete: {
UIApplication.shared.endIgnoringInteractionEvents()
})
})
}
}
推荐阅读
- reactjs - 升级包时持续 TS1005 错误,无法通过回归修复
- python - KivyMD:如何通过按图标从 MDList 项中获取文本
- java - Spring Integration 5.2.3- int-jdbc:inbound-channel-adapter 的死锁问题
- java - Spring Cloud 数据流:异步部署PartitionHanlder
- javascript - 如何捕获来自后端的无效响应并在 vue.js 的 UI 页面中将该错误显示为警报?
- amazon-web-services - 在 Terraform 销毁期间,terraform 在销毁 Auto-scaling 组之前尝试销毁 ECS 集群并且失败了
- azure - 尝试从 Azure Blob 存储下载文件时出现 TimeoutException
- objective-c - Objective C - 以编程方式推送到不在 tabBarController 选项卡中的视图控制器
- css - 如何使用 Tailwind CSS 在表格中居中图像?
- python - sklearn 管道索引不匹配