IOS: отключить второе событие касания при нажатии на ячейку просмотра коллекции или ячейку просмотра таблицы - PullRequest
1 голос
/ 23 апреля 2019

У меня есть ViewController с CollectionView, который загружает четыре возможных ответа на вопрос, заданный в ViewController.Когда пользователь выбирает элемент, вызывается collectionView (_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath), при котором вопрос меняется вместе с массивом ответов (всегда 4), затем вызывается collectionView.reloadData для перерисовки нового вопроса ивозможные ответы.

Все работает отлично, за исключением случаев, когда пользователь быстро нажимает на элемент 2 раза подряд.в этом случае первый выбор регистрирует ответ, а затем просмотр коллекции делает еще одно нажатие (как если бы пользователь снова нажал на следующий вопрос) и, таким образом, отвечает на другой вопрос.

Что я хотел бы сделатьесли возможно, это следующее: 1. отключить сенсорные события при первом касании (при перезагрузке нового вопроса) 2. повторно включить сенсорные события после завершения загрузки reloadData из collectionView.Какую еще проблему я решил с помощью пользовательского класса представления коллекции, взятого из этой темы Как узнать, когда 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
    }
}

У меня естьпомечены как target-c и swift, потому что я не против языка, используемого для решения, а также считаю, что решение / проблема аналогично для uitableview vs uicollectionview.

Любые подсказки?

Ответы [ 2 ]

0 голосов
/ 25 апреля 2019

Мне наконец удалось решить проблему.Хитрость, которая решила это, заключается в том, чтобы поместить 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()
            })
        })
    }
}
0 голосов
/ 24 апреля 2019

Вы можете использовать флаг и установить его в true, когда вы нажмете на ячейку правильного ответа, а затем установите его в false в блоке onComplete reloadData ().

Ex:

var answerChosen: Bool = false

...

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    if answerChosen { return }

    let a = answers[indexPath.row]
    if a.descript.lowercased() == questionAnswer.descript.lowercased() //questionAnswer is the correct answer to the question {
        answerChosen = true
        self.loadNewQuestion()
        self.collectionView.reloadData(onComplete: {
            answerChosen = false    
        })
    } else {
        //warn about wrong answer
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...