UITableView-Swift: une Coche dans UITableViewCell
Je suis en utilisant Xcode 6.0.1, iOS8 et Swift.
J'ai de reproduire dans mon UITableView
le même comportement de la de Verrouillage Automatique de option dans Paramètres->Général. En Objective-C, dans le passé, j'ai écrit
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CheckMarkCellIdentifier = @"CheckMarkCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CheckMarkCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CheckMarkCellIdentifier] autorelease];
}
cell.textLabel.text = ...
cell.detailTextLabel.text = ...;
cell.accessoryType = [indexPath isEqual: self.lastSelectedIndexPath] ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
return cell;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int newRow = indexPath.row;
int oldRow = self.lastSelectedIndexPath.row;
if (newRow != oldRow) {
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:self.lastSelectedIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
self.lastSelectedIndexPath = indexPath;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Cela fonctionne très bien!
Maintenant, dans Swift, j'ai écrit:
override func viewDidLoad() {
super.viewDidLoad()
...
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "categoryCell")
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("categoryCell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = categories[indexPath.row]
let row = indexPath.row;
if let lastIndexPath = self.lastSelectedIndexPath {
cell.accessoryType = (lastIndexPath.row == row) ? UITableViewCellAccessoryType.Checkmark : UITableViewCellAccessoryType.None;
}
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
let newRow = indexPath.row;
var oldRow: Int?
if let lastIndexPath = self.lastSelectedIndexPath {
oldRow = lastIndexPath.row;
let oldCell = self.tableView(tableView, cellForRowAtIndexPath: lastIndexPath)
oldCell.accessoryType = UITableViewCellAccessoryType.None;
}
if (newRow != oldRow) {
let newCell = self.tableView(tableView, cellForRowAtIndexPath: indexPath)
newCell.accessoryType = UITableViewCellAccessoryType.Checkmark;
self.lastSelectedIndexPath = indexPath;
}
}
Et cela ne fonctionne pas. La coche n'apparaît que parfois, et il disparaît quand je scroll. J'ai passé deux heures à comprendre pourquoi, mais sans succès.
Et où est lastSelectedIndexPath censé être déclaré?
OriginalL'auteur Giorgio | 2014-10-07
Vous devez vous connecter pour publier un commentaire.
Le principal problème est que vous appelez
tableView(_:cellForRowAtIndexPath:)
au lieu detableView.cellForRowAtIndexPath(_:)
, et donc de créer une nouvelle cellule au lieu d'obtenir celle qui est actuellement affichée.Voici certains de nettoyage:
Yep, c'est pourquoi il y a un
?
danslastSelectedIndexPath?.row == row
qui devrait prendre soin de cela 🙂De sorte que les deux extraits de code sont-elles équivalentes? J'ai essayé d'utiliser votre fragment de code, mais le résultat est le même.
Non, dans votre cas il y a une situation où
cell.accessoryType
n'est jamais mis entableView(_:cellForRowAtIndexPath:)
qui peut causer le comportement bizarre due à la cellule re-utiliser. -- Quel est le comportement souhaité? En tapant sur une cellule qui est déjà coché décoche une fois de plus? Ou faut-il garder le coche?Et où est lastSelectedIndexPath censé être déclaré?
OriginalL'auteur fluidsonic