J'ai lu partout, alors ne le frappez pas comme un double à moins que ma recherche n'ait été complètement horrible.

Fondamentalement, j'ai une petite table (5 lignes fixes) mais ils ont des index qui leur sont associés dans un tuple (c'est pourquoi j'utilise la méthode dynamique plutôt que statique.

Le but du joueur est d'échanger les cellules. Je n'utilise pas de pointe pour peupler ces cellules, voici comment.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cellID = "Cell"
    let customCell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! DefinitionMatchTableViewCell

    customCell.background.layer.borderWidth = CGFloat(2.0)

    if tableView == nameTableLeft{
        customCell.textToDislay!.text = nameList[indexPath.row].0
        customCell.background.layer.borderColor = UIColor(red: 255/255, green: 192/255, blue: 1/255, alpha: 1.0).cgColor
        let cellIDFromTuple = nameList[indexPath.row].1
       customCell.tag = cellIDFromTuple
    }

    if tableView == definitionTableRight{
        customCell.textToDislay!.text = definitionList[indexPath.row].0
        customCell.background.layer.borderColor = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.2).cgColor
        let cellIDFromTupleForDefinition = definitionList[indexPath.row].1
        customCell.tag = cellIDFromTupleForDefinition
    }

    customCell.background.backgroundColor = UIColor.clear
    customCell.backgroundColor = UIColor.clear
    return customCell
}

Maintenant, le problème est que sur un iPhone SE, les 5 cellules ne peuvent pas s'adapter, ce qui entraîne la perte de son ID de référence lors de la vérification de la correspondance des valeurs. Cela rend le jeu impossible à terminer, j'ai besoin d'un moyen pour que je puisse remplir la table avec une valeur d'index associée à chaque chaîne mais pour que la table ne réutilise pas la cellule mais elle reste en mémoire.

La seule méthode à laquelle je peux penser est d'écrire une table statique avec les données, mais de fournir ensuite à chaque cellule un index invisible qu'elle porte associé à la chaîne. Cependant, je préfère de loin le faire de manière dynamique.

Tout conseil sur le maintien de l'état de ces cellules serait grandement apprécié. Merci!

MODIFIER 1

Voici comment je vérifie les réponses en fonction de mes valeurs d'index dans le tableau. J'imagine que le problème vient de .indexPathsForVisibleRows car certains ne sont pas visibles

    for index in nameTableLeft.indexPathsForVisibleRows!{
            let leftCell = nameTableLeft.cellForRow(at: index) as? DefinitionMatchTableViewCell
            let rightCell = definitionTableRight.cellForRow(at: index) as? DefinitionMatchTableViewCell

if nameTableLeft.cellForRow(at: index)?.tag == definitionTableRight.cellForRow(at: index)?.tag{
                leftCell?.background.layer.borderColor = UIColor.green.cgColor
                rightCell?.background.layer.borderColor = UIColor.green.cgColor
                counter += 1
            }else{
                leftCell?.background.layer.borderColor = UIColor.red.cgColor
                rightCell?.background.layer.borderColor = UIColor.red.cgColor
            }
        }

Comme vous pouvez le voir, je vérifie ensuite que les valeurs correspondent aux balises. Cependant, j'ai du mal avec ce concept si j'utilise quelque chose de différent.

Mon modèle

var nameList : [(String, Int)] = [("Trojan", 0),
                                  ("Virus", 1),
                                  ("Spyware", 2),
                                  ("Ransomware", 3),
                                  ("Leakware", 4)]
var definitionList : [(String, Int)] = [("Attaches onto another program. Replicates itself. Something loaded onto your device without your knowledge. Continues to spread", 0),
                                        ("When malware is disguised as something else. Usually an e-mail attachment", 1),
                                        ("Tracks a user's actions, this includes login details, internet habits and any secure accounts", 2),
                                        ("Locks a device or encrypts files and demands money to unlock it", 3),
                                        ("Threatens to distribute your information", 4)]

Modifier 2

Grâce à un peu d'aide dans les réponses, j'avais décidé d'ajouter ceci à ma vérification des réponses.

 for answerIndex in 0...4{
            if definitionList[answerIndex].1 == nameList[answerIndex].1{
                print("MATCH")
                counter += 1
            }else{
                print("NO MATCH")
            }
        }

Je mélange à la fois les listes de définitions et de noms pour commencer. Je décide ensuite de regarder les deux index placés dans le tuple en fonction de la longueur totale des tables. Malheureusement, j'ai dû recourir à des nombres magiques, vous ne pouvez pas parcourir un tuple.

Donc, cette petite boucle décide si les index s'alignent dans mes tuples et s'ils le font, c'est correct sinon ce n'est pas le cas. Merci encore à tous pour l'aide.

1
CardDeath 17 janv. 2017 à 15:32

2 réponses

Meilleure réponse

J'ai également résolu un problème similaire. Mon conseil est de continuer à réutiliser les cellules. Stockez les données correspondant à chaque cellule en externe dans une classe de modèle distincte. Puis stockez-le dans un tableau mutable. Lorsque vous mélangez les cellules, mélangez les données dans le tableau mutable.

Cela peut être fait de la manière suivante.

La classe model

class model: NSObject {

   var name: String = ""
   var definition: String = ""
   var type: String = ""

   required init(name: String, definition: String, type: String) {
       super.init()

       self.name = name
       self.definition = definition
       self.type = type
   }
}

Personnalisé UITableViewCell - exemple trivial pour différentes mises en page

class CustomTableViewCell: UITableViewCell {

    var nameLabel: UILabel = UILabel()
    var definitionLabel: UILabel = UILabel()

    override init(style: UITableViewCellStyle, reuseIdentifier: String?)      
    {
       super.init(style: style, reuseIdentifier: reuseIdentifier)

       nameLabel.textColor = UIColor.black
       nameLabel.font = UIFont.systemFont(ofSize: 15)
       nameLabel.textAlignment = NSTextAlignment.left
       self.contentView.addSubview(nameLabel)

       definitionLabel.textColor = UIColor.brown
       definitionLabel.font = UIFont.systemFont(ofSize: 15)
       definitionLabel.textAlignment = NSTextAlignment.right
       self.contentView.addSubview(definitionLabel)
    } 

    required init?(coder aDecoder: NSCoder) {
       fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
       super.layoutSubviews()

       nameLabel.frame = CGRect(x: 10, y: 10, width:   self.contentView.frame.size.width - 20, height: self.contentView.frame.size.height - 20)
       definitionLabel.frame = CGRect(x: 10, y: 10, width: self.contentView.frame.size.width - 20, height: self.contentView.frame.size.height - 20)
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

    }

}

Enregistrement de la cellule:

self.tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "reuseIdentifier")

Utilisation du CustomTableViewCell selon le modèle:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)

    // Configure the cell...
    if model.type == "name" {
        cell.nameLabel.text = model.name
        cell.definitionLabel.isHidden = true
    }else if model.type == "definition" {
        cell.definitionLabel.text = model.definition
        cell.nameLabel.isHidden = true
    }

    return cell
}

La partie cellules mobiles:

let mutableArray:[model] = [model1, model2, model3, model4, model5] // model class holds data for each cell

func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
     let source = sourceIndexPath.row;
     let destination = destinationIndexPath.row;

     let sourceModel = mutableArray[source]
     let destinationModel = mutableArray[destination]

     mutableArray[source] = destinationModel
     mutableArray[destination] = sourceModel
}

N'hésitez pas à commenter si vous avez des doutes sur cette implémentation. N'hésitez pas à suggérer des modifications pour améliorer cela :)

Modifier: -

Même s'il s'agit d'un tuple avec sa position d'index, vous pouvez modifier les valeurs lorsque les lignes sont déplacées en conséquence.

var nameList : [(String, Int)] = [("Trojan", 0),
                                  ("Virus", 1),
                                  ("Spyware", 2),
                                  ("Ransomware", 3),
                                  ("Leakware", 4)]

let source = sourceIndexPath.row
let destination = destinationIndexPath.row

var sourceTuple: (String, Int) = nameList[source]
var destinationTuple: (String, Int) = nameList[destination]

sourceTuple.1 = destination
destinationTuple.1 = source

nameList[destination] = sourceTuple
nameList[source] = destinationTuple
3
KrishnaCA 18 janv. 2017 à 19:16

Tout d'abord, vous devez vous attendre à ce que les cellules soient réutilisées et non à stocker l'état dans vos cellules. Mais si vous voulez une réponse rapide, définissez un identifiant de réutilisation différent pour chaque cellule.

2
Jon Rose 17 janv. 2017 à 12:51