Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

447
Visualizações
How can I enable selecting multiple collection view cells at once with multitouch?

I am writing an iOS card game. I display the player's cards in a collection view. The player can select one or more cards by tapping on them, and then press a deal button to deal the selected cards.

I want to allow the user to use multiple fingers to select multiple cards at once. For example, if the user wants to select 2 cards, he just needs to tap the two cards at the same time, with two fingers, and they will both be selected. It seems like that by default, UICollectionView does not allow this. When I tap with 2 fingers, only one of the cards will be selected, even though the isMultipleTouchEnabled property in UIView is already set to true.

Note that I am not asking about how to allow a user to select multiple items in a collection view. I can and did already do that with allowsMultipleSelection = true. What I am asking is how to allow the user to select 2 cells with 2 fingers (or n cells with n fingers).

I found this question, but that seems to be about how to show a border around a cell when it is selected.

I also looked into the documentation of UICollectionView but I found no property that controls this.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

First let's understand exactly what the problem is. The collectionView has a bunch of UIGestureRecognisers attached to it (for pan, touch, zoom, etc). Each recogniser has the same state machine of possible->recognised-> changed-> ended/failed. Each recogniser has a clear start beginning and end. Once the tap gesture has started in one location it is not going to begin in another location. When a person 1) touches down point A 2) touches down point B 3) touches up point A 4) touches up point B that the gesture completely ignores point B because it is "focused" on point A.

The second problem is that if you touch at two points at the exact same time the method of tapGesture.location(in: view) will give you the average of those two location.

However we solve this the first step is to disable the collectionView tapGesture - it is not doing what we want :

  self.collectionView.allowsMultipleSelection = true
  self.collectionView.allowsSelection = false;

Next we are going to add our own tap gestures to each cell individually. This is explicitly NOT recommend by apple ("You should always attach your gesture recognizers to the collection view itself—not to a specific cell or view."1) but it will work:

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
 ...
  cell.addGestureRecognizer(UITapGestureRecognizer.init(target: self, action: #selector(didTap(tapper:))))
  ...
  return cell;
}

@objc func didTap(tapper:UIGestureRecognizer) {
  if let cell = tapper.view as? UICollectionViewCell{
    if let index = collectionView.indexPath(for: cell) {
      if collectionView.indexPathsForSelectedItems?.contains(index) ?? false {
        collectionView.deselectItem(at: index, animated: true)
        cell.isSelected = false
      }else{
        collectionView.selectItem(at: index, animated: true, scrollPosition: [])
        cell.isSelected = true
      }
    }
  }
}
over 4 years ago · Santiago Trujillo Relatório

0

You could add multiple gesture recognizers for the number of touches you want to support:

collectionView.allowsMultipleSelection = true
// allowing up to 5 finger touches, increase if you want for more :)
for i in 2...5 {
    let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
    gestureRecognizer.numberOfTouchesRequired = i
    gestureRecognizer.delegate = self
    collectionView.addGestureRecognizer(gestureRecognizer)
}

, and have the controller to look for the cells that were touched:

@objc private func handleTap(_ gestureRecognizer: UIGestureRecognizer) {
    // perform the action only after the touch ended
    guard gestureRecognizer.state == .ended else { return }

    for i in 0..<gestureRecognizer.numberOfTouches {
        let location = gestureRecognizer.location(ofTouch: i, in: collectionView)
        // if we have a cell at that point, toggle the selection
        if let indexPath = collectionView.indexPathForItem(at: location) {
            if collectionView.indexPathsForSelectedItems?.contains(indexPath) == true {
                collectionView.deselectItem(at: indexPath, animated: true)
            } else {
                collectionView.selectItem(at: indexPath, animated: true, scrollPosition: [])
            }
        }
    }
}
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda