首页 > 解决方案 > 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的解决方案/问题是相似的。

任何提示?

标签: iosuitableviewuicollectionview

解决方案


我终于设法解决了这个问题。解决它的技巧是将 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()
            })
        })
    }
}

推荐阅读