2009-11-17 10 views
26

Sono un po 'confuso circa gli accessori della cella di visualizzazione tabella delle impostazioni.UITableViewCell Tipo di accesso selezionato Toccare e impostare altro deselezionato

ho fissato due sezioni in mia tabella

  • casa
  • Ufficio

Quello che voglio è la seguente ....

  • Quando toccare utente qualsiasi la cella
  • La cella viene selezionata &
    • voglio impostare controllato (impostare il tipo di UITableViewCell accessorio -checked di cellula sfruttato)
  • E anche tipo di accessorio di tutti gli altri cellulare ora deve impostare a
    • vista uitable tipo di accessorio cellule nessuno

Ho provato il seguente codice. Ma ho trovato che indexpath.row & indexpath.section è proprietà readonly.

// Override to support row selection in the table view. 
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {  
    [tblProfileView deselectRowAtIndexPath:indexPath animated:YES]; 
    int i,max; 
    UITableViewCell *x; NSIndexPath *tt; 

    for(i=0;i<[tblProfileView numberOfRowsInSection:0];i++) 
    { 
     tt.row=i; tt.section=0; 
     x=[tblProfileView cellForRowAtIndexPath:]; 
     [x setAccessoryType:UITableViewCellAccessoryNone]; 
    } 
    for(i=0;i<[tblProfileView numberOfRowsInSection:1];i++) 
    { 
     tt.row=i; tt.section=1; 
     x=[tblProfileView cellForRowAtIndexPath:tt]; 
     [x setAccessoryType:UITableViewCellAccessoryNone]; 
    } 

    x=[tblProfileView cellForRowAtIndexPath:indexPath]; 
    [x setAccessoryType:UITableViewCellAccessoryCheckmark]; 
    // Navigation logic may go here -- for example, create and push another view controller. 
    // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil]; 
    // [self.navigationController pushViewController:anotherViewController animated:YES]; 
    // [anotherViewController release]; 
} 

risposta

48

vorrei tenere traccia dei datiche devono essere controllati e cambiare la cella in tableView: didSelectRowAtIndexPath: e aggiornare cui i dati vengono controllati in tableView: cellForRowAtIndexPath: in questo modo:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    // do usual stuff here including getting the cell 

    // determine the data from the IndexPath.row 

    if (data == self.checkedData) 
    { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } else { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
    } 

    return cell; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    // determine the selected data from the IndexPath.row 

    if (data != self.checkedData) { 
     self.checkedData = data; 
    } 

    [tableView reloadData]; 
} 
+1

Questo non è il modo giusto per farlo, poiché si chiama reloadData (che può essere costoso a seconda dei dati). Puoi semplicemente: lasciare cell = tableView.cellForRowAtIndexPath (indexPath) cell? .accessoryType = (yourTest)? .Controlla: .Nessuno – Max

+0

In realtà devi fare quasi entrambe le cose. Esegui l'aggiornamento direttamente come indicato da Max e configura la cella in cellForRowAtIndexPath o gli stati della cella vengono confusi quando si scorre l'elenco. – marsbear

+1

Oh e implementare anche didDeselectRowAtIndexPath in modo da poter deselezionare nuovamente le celle. – marsbear

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

    UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath]; 

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


} 

inoltre è necessario rimuovere l'accessorio segno di spunta sulla cellForRowAtIndexPath

if ([selectedOptionsArray indexOfObject:cell.textLabel.text] != NSNotFound) { 
    cell.accessoryType = UITableViewCellAccessoryCheckmark; 
}else{ 
    cell.accessoryType = UITableViewCellAccessoryNone; 
} 
+1

Questo è diverso da quello che l'OP chiedeva. Non è stato menzionato il fatto di consentire selezioni multiple o zero. Quando uno si accende, gli altri devono spegnersi.La soluzione consente all'utente di attivare e disattivare una riga da sola e presumibilmente che selectedOptionsArray memorizzi più opzioni selezionate anziché una sola come richiesto. – Craig

+1

@craig Sì, sei perfetto. Ma stavo usando questo codice per attivare le opzioni (righe) per la mia app. Ho pensato che potesse essere utile, lo snippet in qualche modo basato su gerry3, ma non ho usato [tableview reloaddata]. – palaniraja

+0

Grazie @palaniraja Mi sono imbattuto in questo post alla ricerca della soluzione, quindi ho potuto utilizzare l'elenco delle tabelle per la selezione degli elementi. – robmcm

13

Dichiarare una variabile int chiamata prev e implementare questo metodo: -

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

UITableViewCell *cell =[tableView cellForRowAtIndexPath:indexPath]; 

    if (cell.accessoryType==UITableViewCellAccessoryNone) 
    { 
     cell.accessoryType=UITableViewCellAccessoryCheckmark; 
     if (prev!=indexPath.row) { 
     cell=[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:prev inSection:0]]; 
     cell.accessoryType=UITableViewCellAccessoryNone; 
     prev=indexPath.row; 
    } 

} 
else{ 
    cell.accessoryType=UITableViewCellAccessoryNone; 
} 
} 
+1

Bella risposta, molto in ordine. – AndyDunn

+0

Buona risposta, l'ho tradotto in Swift sotto. –

3

Un modo più breve e più semplice per implementare la logica per segno di spunta nella riga selezionata solo .....


1. Creare un oggetto globale di NSIndexPath ..

selectedIndexPathForCheckMark= [[NSIndexPath alloc] init]; 

2. In didSelectRowAtIndexPath ..

// assiging indexPath selezionato l'oggetto dichiarato

selectedIndexPathForCheckMark = indexPath; 
[tableView reloadData]; 

3. in cellForRowAtIndexPath ..

if ([selectedIndexPathForCheckMark isEqual:indexPath]) { 
    [cell setAccessoryType:UITableViewCellAccessoryCheckmark]; 
}else { 
    //setAccessoryType None if not get the selected indexPath 
    [cell setAccessoryType:UITableViewCellAccessoryNone]; 
} 
1

Ecco come lo faccio con celle statiche, e bypassando cellForRow

Creare una var che memorizza la posizione del "controllato" cella.

NSInteger _checkedCell; 

Poi basta implementare willDisplayCell e didSelectRow metodi come questo.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 
    if (_checkedCell == indexPath.row) { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } 
    else { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
    } 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    _checkedCell = indexPath.row; 
    [self.tableView reloadData]; 
} 
1

ho conosciuto questa domanda è abbastanza vecchio, ma qui è la versione Swift in base alla risposta del Blackberry (che ho votato per la via)

import UIKit 
 

 
class PlacesViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource { 
 

 
    var placesArray = NSMutableArray() 
 
    
 
    var previousCheckedIndex = 0 
 
    
 
    override func viewDidLoad() { 
 
     super.viewDidLoad() 
 

 
     self.placesArray.addObject("Tandil") 
 
     self.placesArray.addObject("Balcarce") 
 
     self.placesArray.addObject("Mar del Plata") 
 
     
 
     self.tableView.rowHeight = UITableViewAutomaticDimension 
 
    } 
 

 
    
 
    
 
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
 
     return self.placesArray.count 
 
    } 
 
    
 
    
 
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
 
     
 
     var cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell 
 

 
     cell.textLabel?.text = self.placesArray.objectAtIndex(indexPath.row) as? String 
 
     
 

 
     return cell 
 
    } 
 
    
 
    
 
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
 

 
     if (indexPath.row != previousCheckedIndex) { 
 
      var cell: UITableViewCell = self.tableView.cellForRowAtIndexPath(indexPath)! 
 
      if (cell.accessoryType == UITableViewCellAccessoryType.None) { 
 
       cell.accessoryType = UITableViewCellAccessoryType.Checkmark 
 
       if (previousCheckedIndex != indexPath.row) { 
 
        cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: previousCheckedIndex, inSection: 0))! 
 
        cell.accessoryType = UITableViewCellAccessoryType.None 
 
        previousCheckedIndex = indexPath.row 
 
       } 
 
      } else { 
 
       cell.accessoryType = UITableViewCellAccessoryType.None 
 
      } 
 
     
 
      tableView.reloadData() 
 
     } 
 
    } 
 
}

0

In Swift 2.0 con accessorio personalizzatoVisualizza uitableviewcell con swift

1º Creazione di Globar var IndexPa esimo

var indexSelected = NSIndexPath() 

2º In didSelectRowAtIndexPath

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
     indexSelected = indexPath 
     TB_Lojas.reloadData() 
    } 

3a nella cellForRowAtIndexPath:

if SelectedIndexPath == indexPath { 
       let img = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20)) 
       img.image = UIImage(named: "check") 
       cell.accessoryView = img 
      }else{ 
       let img = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20)) 
       img.image = UIImage(named: "uncheck") 
       cell.accessoryView = img 
      } 
} 
0

si Considerando vuole solo per mantenere una singola selezione, e se si dispone di un personalizzato UITableViewCell, vorrei raccomandare quanto segue.

Nella tua UITableViewController

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    //... 
    let data = dataArray[indexPath.row] 
    if data.isSelected { 
     tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: .None) 
    } 
    //... 

    return cell 
} 

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    let data = dataArray[indexPath.row] 
    data.isSelected = true 
    let cell = tableView.cellForRowAtIndexPath(indexPath) 
    cell?.setSelected(true, animated: true) 
} 

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { 
    let data = dataArray[indexPath.row] 
    data.isSelected = false 
    let cell = tableView.cellForRowAtIndexPath(indexPath) 
    cell?.setSelected(false, animated: true) 
} 

Nel personalizzato UITableViewCell

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

    // Configure the view for the selected state 
    self.accessoryType = .None 
    if selected { 
     self.accessoryType = .Checkmark 
    } 
} 

Finché allowsMultipleSelection non è abilitato, si gestirà automaticamente deselezionando altre cellule quando si seleziona una nuova. Se allowMultipleSelection è abilitato, funzionerà anche, tranne che dovrai semplicemente toccare di nuovo per deselezionare.

0

Risposta di BlackBerry in Swift 3. UITableView con celle standard, selezionando 0 o 1 celle.

private var previousSelection = NSIndexPath() 

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    tableView.deselectRow(at: indexPath, animated: true) 
    let cell = tableView.cellForRow(at: indexPath)! 
    if cell.accessoryType == .none { 
     cell.accessoryType = .checkmark 
     selection = indexPath 

     if previousSelection == IndexPath() { 
      previousSelection = indexPath 
     } else if previousSelection != indexPath { 
      let previousCell = tableView.cellForRow(at: previousSelection) 
      previousCell?.accessoryType = .none 
      previousSelection = indexPath 
     } 
    } else if cell.accessoryType == .checkmark { 
     cell.accessoryType = .none 
     selection = IndexPath() 
    } 

} 
Problemi correlati