web-dev-qa-db-fra.com

UITableView Checkmark SEULEMENT UNE ligne à la fois

Vous penseriez que ce serait facile. Avec ce code, je peux vérifier plusieurs lignes dans une table, mais ce que je veux, c’est de ne faire vérifier qu’une ligne à la fois. Si un utilisateur sélectionne une autre ligne, je souhaite que l'ancienne ligne soit simplement désélectionnée AUTOMATIQUEMENT. Je ne sais pas comment faire ça. Voici mon code:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

[tableView deselectRowAtIndexPath:indexPath animated:YES];


UITableViewCell *theCell = [tableView cellForRowAtIndexPath:indexPath];

if (theCell.accessoryType == UITableViewCellAccessoryNone) {
    theCell.accessoryType = UITableViewCellAccessoryCheckmark;
    }

    else if (theCell.accessoryType == UITableViewCellAccessoryCheckmark) {
    theCell.accessoryType = UITableViewCellAccessoryNone;
    }
}

Merci pour toute aide que vous pouvez prêter! 

17
Jupiter869

Le meilleur moyen est de définir le type d'accessoire dans cellForRowAtIndexPath et d'utiliser didSelectRowAtIndexPath pour n'enregistrer que le chemin devrait être sélectionné, puis appeler reloadData.

24
Phillip Mills
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath   *)indexPath
{
     [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}

La version Swift serait:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark
}

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .None
}

Swift 3 update :

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
78
Ujwal Manjunath

Vous pouvez créer une nouvelle variable pour suivre l'index sélectionné dans didSelectRowAtIndex.

int selectedIndex;

dans votre cellForRowAtIndexPath

if(indexPath.row == selectedIndex)
{
   cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
   cell.accessoryType = UITableViewCellAccessoryNone;
}

et dans votre didSelectRowAtIndex

selectedIndex = indexPath.row;
[tableView reloadData];
21
John Paul Manoza

Vous n'avez pas besoin (et ne devriez pas) simplement recharger la table après chaque sélection. 

Apple a une bonne documentation sur la façon de gérer une liste de sélection. Voir Listing 6-3 pour un exemple.

C’est plus ou moins la même réponse que d’autres, mais j’ai pensé ajouter un peu plus de détails. 

Ce que vous voulez faire, c'est enregistrer le chemin IndexPath sélectionné en cours dans une variable et l'utiliser dans didSelectRowAtIndexPath pour supprimer l'ancienne coche. C'est également à cet endroit que vous ajouterez la nouvelle coche. 

Vous devez également vous assurer de cocher/décocher les cases à cocher dans cellForRowAtIndexPath, sinon, si votre liste est volumineuse et que les cellules sont réutilisées, il semblera que plusieurs lignes sont sélectionnées. Ceci est un problème avec certaines des autres réponses. 

Voir l'exemple de Swift 2.0 ci-dessous:

// for saving currently seletcted index path
var selectedIndexPath: NSIndexPath? = NSIndexPath(forRow: 0, inSection: 0)  // you wouldn't normally initialize it here, this is just so this code snip works
// likely you would set this during cellForRowAtIndexPath when you dequeue the cell that matches a saved user selection or the default

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    // this gets rid of the grey row selection.  You can add the delegate didDeselectRowAtIndexPath if you want something to happen on deselection
    tableView.deselectRowAtIndexPath(indexPath, animated: true) // animated to true makes the grey fade out, set to false for it to immediately go away

    // if they are selecting the same row again, there is nothing to do, just keep it checked
    if indexPath == selectedIndexPath {
        return
    }

    // toggle old one off and the new one on
    let newCell = tableView.cellForRowAtIndexPath(indexPath)
    if newCell?.accessoryType == UITableViewCellAccessoryType.None {
        newCell?.accessoryType = UITableViewCellAccessoryType.Checkmark
    }
    let oldCell = tableView.cellForRowAtIndexPath(selectedIndexPath!)
    if oldCell?.accessoryType == UITableViewCellAccessoryType.Checkmark {
        oldCell?.accessoryType = UITableViewCellAccessoryType.None
    }

    selectedIndexPath = indexPath  // save the selected index path

    // do whatever else you need to do upon a new selection
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
    // if this is the currently selected indexPath, set the checkmark, otherwise remove it
    if indexPath == selectedIndexPath {
        cell.accessoryType = UITableViewCellAccessoryType.Checkmark
    } else {
        cell.accessoryType = UITableViewCellAccessoryType.None
    }
}
16
jeffjv

Vous n'avez pas besoin de recharger la tableView.

Voir le code ci-dessous:

Déclarez une variable NSIndexPath lastSelectedIndexPath pour votre classe

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    if(lastSelectedIndexPath) {

        UITableViewCell *lastCell = [tableView cellForRowAtIndexPath:lastSelectedIndexPath];
        [lastCell setAccessoryView:nil];
    }

    UITableViewCell *currentCell = [tableView cellForRowAtIndexPath:currentIndexPath];
    [currentCell setAccessoryView:UITableViewCellAccessoryCheckmark];

    lastSelectedIndexPath = indexPath;
}
8

La méthode la plus simple consiste à enregistrer le chemin IndexPath sélectionné et à le vérifier dans cellForRowAtIndexPath.

ci-joint le code:

étape 1: initialiser selectedIndexPath selectedIndexPath = [[NSIndexPath alloc] init];

étape 2: dans cellForRowAtIndexPath

if([selectedIndexPath isEqual:indexPath]){
    [checkMark setHidden:NO];
} else {
    [checkMark setHidden:YES];
}

étape 3: Dans didSelectRowAtIndexPath

selectedIndexPath = indexPath;
[tableView reloadData];

Ça devrait marcher marcher essayer ceci Njoy :)

4
Ranganatha G V

Je pense que https://stackoverflow.com/a/5960016/928599 vous aidera.
Je l'ai utilisé et ça marche aussi avec deselectRowAtIndexPath!

4
mohsinj

Pour Swift 3, les actions suivantes ont fonctionné pour moi:

override func viewDidLoad() {
    super.viewDidLoad()

    // allow cells to be selected
    tableView.allowsSelection = true

    // ensure that deselect is called on all other cells when a cell is selected
    tableView.allowsMultipleSelection = false
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableVIew.cellForRow(at: indexPath as IndexPath)?.accessoryType = .checkmark
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    tableVIew.cellForRow(at: indexPath as IndexPath)?.accessoryType = .none
}
2

Essaye ça: 

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if indexPath.section == 1 {
        // un-select the older row
        if let selected = self.LastSelected {
            tableView.cellForRowAtIndexPath(selected)?.accessoryType = .None
        }

        // select the new row
        tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = UITableViewCellAccessoryType.Checkmark
        self.LastSelected = indexPath
    }
}
1
alcedo

Dans Swift, ce qui suit fonctionne parfaitement:

lastSelectedIndexPath = NSIndexPath(forRow: 1, inSection: 0)//Row will be the previous selected row


    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell:LabelsSelectionCell = tableView.dequeueReusableCellWithIdentifier("LabelsSelectionCell", forIndexPath: indexPath) as! LabelsSelectionCell
    cell.setCellLael(labelOptionsArray[indexPath.row])
    if lastSelectedIndexPath == indexPath
    {
        cell.setCellCheckedStatus(true)
    }
    return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
    if let _ = lastSelectedIndexPath
    {
        let lastCell:LabelsSelectionCell = tableView.cellForRowAtIndexPath(lastSelectedIndexPath!) as! LabelsSelectionCell
        lastCell.setCellCheckedStatus(false)
    }
    let currentCell:LabelsSelectionCell = tableView.cellForRowAtIndexPath(indexPath) as! LabelsSelectionCell
    currentCell.setCellCheckedStatus(true)

    lastSelectedIndexPath = indexPath

    tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
1
msmq

testé et résolu essayer cela sa a fonctionné parfaitement

ajoutez ceci comme variable globale 

var selectedIndexPath = NSIndexPath(row: 0, section: 0)

Ajouter ceci dans la méthode didselect

        // old one check off
        if indexPath != selectedIndexPath as IndexPath {
            let oldCell = categorytable.cellForRow(at: selectedIndexPath as IndexPath)
            if oldCell?.accessoryView != nil {
                oldCell?.accessoryView = nil
            }
            else {
                let imageName = "checkmark"
                let image: UIImageView = UIImageView(image: UIImage(named: imageName))
                cell.accessoryView = image
            }
        }
        // the new one on

        if  cell.accessoryView == nil {
            let imageName = "checkmark"
            let image: UIImageView = UIImageView(image: UIImage(named: imageName))
            cell.accessoryView = image
        }
        else {
            cell.accessoryView = nil
        }
0
hardik

Mon chemin est de désélectionner les autres cellules lors de la sélection:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = ....

    if condition {
        cell.accessoryType = .checkmark
        tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.bottom)
    } else {
        cell.accessoryType = .none
    }

    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    for row in 0...tableView.numberOfRows(inSection: 0) {
        if row == indexPath.row {continue}
        tableView.deselectRow(at: IndexPath(row: row, section: 0), animated: true)
    }

    if let cell = tableView.cellForRow(at: indexPath) {
        cell.accessoryType = .checkmark
    }
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath)
    cell?.accessoryType = .none
}
0
protspace

Voici ce que je suis venu quand j'ai eu ce problème.
Ce code est implémenté dans la dernière version de Swift, à compter d’aujourd’hui ...
Pour plus d’informations et/ou le fichier d’extension, consultez le Github Gist de cet extrait.

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {       
    if let sip = selectedIndex {
        tableView.deselectRow(at: sip, animated: false)
    }
    selectedIndex = indexPath
}

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    if selectedIndex?.row == indexPath.row {
        selectedIndex = nil
    }
}
0
gchriswill
Swift iOS

     var checkedIndexPath : NSIndexPath?

     // table row which row was selected
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)

        println("Section #\(indexPath.section)! You selected cell #\(indexPath.row)!")

        if (self.checkedIndexPath != nil) {
            var cell = tableView.cellForRowAtIndexPath(self.checkedIndexPath!)
            cell?.accessoryType = .None
        }

        var cell = tableView.cellForRowAtIndexPath(indexPath)
        cell?.accessoryType = .Checkmark

        self.checkedIndexPath = indexPath

    }// end tableView
0
Vinod Joshi

Dans Swift 2.0, j'ai utilisé ceci:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    if((lastSelectedIndexPath) != nil) {
        let lastCell = tableView.cellForRowAtIndexPath(lastSelectedIndexPath)
        lastCell?.accessoryType = UITableViewCellAccessoryType.None
    }

    let currentCell = tableView.cellForRowAtIndexPath(indexPath)
    currentCell?.accessoryType = UITableViewCellAccessoryType.Checkmark

    lastSelectedIndexPath = indexPath

}
0
Dasoga