collectionView didSlectRow ошибка - PullRequest
0 голосов
/ 27 мая 2019

Здравствуйте, на конкретном viewController моего проекта у меня есть UICollectionView с пользовательской ячейкой класса.Но у меня есть большая проблема в том, что эта функция:

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("tapped on a cell")
    }

, когда происходит щелчок по ячейке, и мгновенный выпуск (обычный щелчок) ничего не делает, просто ничего.

если я нажимаю и удерживаюПримерно через 1 с, не отпуская палец, он становится серым, подсвечивается

И если я нажму и удерживаю не менее 3 секунд, отпустите палец, didSelectItemAt выполняется правильно.Я пытался сделать то же самое на другом проекте, и это прекрасно работает, но не на этом VC, и я действительно не нахожу проблему.VC Bugged имеет класс addTest в Main.storyboard

Ответы [ 2 ]

1 голос
/ 27 мая 2019

Понимание Моджтабы Хоссейни очень умно, но данный ответ может быть не совсем правильным.

Оказывается, на главном экране есть UITapGestureRecognizer; если он распознает до нажатия на ячейку, он предотвращает выбор ячейки. Но если вы просто установите cancelsTouchesInView в false на этом распознавателе жестов, то они оба будут работать, и это вряд ли будет тем, что нужно. Мы обязательно хотим, чтобы касание ячейки, а не касание распознавателя жестов касания.

Таким образом, правильное решение состоит в том, чтобы дать распознавателю жестов касания делегата и реализовать gestureRecognizerShouldBegin. Здесь мы смотрим, чтобы увидеть , где кран. Если оно находится в пределах ячейки, мы возвращаем false; в противном случае мы возвращаем true. Таким образом, мы являемся посредником между касанием ячейки и касанием распознавателя жестов.

Вот возможная реализация, продемонстрированная в очень упрощенной форме:

extension UIView {
    func isDescendant(of whattype:UIView.Type) -> Bool {
        var sup : UIView? = self.superview
        while sup != nil {
            if (whattype == type(of:sup!)) {
                return true
            }
            sup = sup!.superview
        }
        return false
    }
}

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UIGestureRecognizerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        let t = UITapGestureRecognizer(target: self, action: #selector(tap))
        self.view.addGestureRecognizer(t)
        t.delegate = self
    }

    @objc func tap(_:UIGestureRecognizer) {
        print("tap")
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("select")
    }

    func gestureRecognizerShouldBegin(_ gr: UIGestureRecognizer) -> Bool {
        if let v = gr.view {
            let loc = gr.location(in: v)
            if let v2 = v.hitTest(loc, with: nil) {
                return !v2.isDescendant(of: UICollectionViewCell.self)
            }
        }
        return true
    }
}

Как видите, мы смотрим, находится ли кран внутри ячейки представления коллекции; если это так, наш распознаватель жестов не сможет распознать, и выбор будет выполнен немедленно.

1 голос
/ 27 мая 2019

Возможно, под представлением коллекции есть UIGesture или другая интерактивная вещь. Вы должны ОТКЛЮЧИТЬ его способность cancel touches in view в построитель интерфейса :

Attributes inspector

или в коде:

myTapGestureRecognizer.cancelsTouchesInView = false
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...