2014-04-29 3 views
0

J'ai un UISwitch dans mon prototype UITableViewCell.UISwitch dans UITableView Bogue

Le problème est que, lorsque j'active l'un des commutateurs, l'un des commutateurs non affichés s'allume également.

Cela ne se produit pas dans la version iPad où toutes les cellules sont affichées.

Voici un code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *identifier = @"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; 

    Notification *notification = [notifications objectAtIndex:indexPath.row]; 

    UILabel *titleLabel = (UILabel *) [cell viewWithTag:100]; 
    UISwitch *newsSwitch = (UISwitch *) [cell viewWithTag:101]; 
    UIImageView *imageView = (UIImageView *) [cell viewWithTag:102]; 

    [titleLabel setText:[notification name]]; 
    [imageView setImage:[UIImage imageNamed:[notification image]]]; 

    BOOL isOn = [storage boolForKey:[NSString stringWithFormat:@"notification_%@", [notification name]]]; 
    [newsSwitch setOn:isOn]; 
    [newsSwitch setTag:indexPath.row]; 
    [newsSwitch addTarget:self action:@selector(didChangeStateForSwitch:) forControlEvents:UIControlEventValueChanged]; 

    return cell; 
} 
+0

Vous voulez dire qu'un interrupteur qui n'est pas encore à l'écran s'allume également? Alors le bug est le plus probable dans votre méthode 'didChangeStateForSwitch:', veuillez mettre à jour votre question et nous montrer le code de cette méthode. – DarkDust

+0

J'ai retiré le code de didChangeStateForSwitch: et le comportement est le même. –

Répondre

1

Votre problème est que vous devez d'abord interroger le commutateur via son tag:

UISwitch *newsSwitch = (UISwitch *) [cell viewWithTag:101]; 

Mais plus tard sur, vous modifiez cette balise:

[newsSwitch setTag:indexPath.row]; 

Ainsi, lorsque la cellule obtient r eused, le switch ne sera pas trouvé car maintenant son tag n'est plus 101. Par conséquent, le commutateur sera bloqué dans son ancien état.

Vous pouvez facilement vérifier cela en ajoutant un NSLog(@"Switch: %@", newsSwitch); après avoir interrogé le commutateur. Vous verrez que le résultat est Switch: (null) pour les lignes où vous avez des valeurs de commutation "incorrectes".

La solution est de ne pas modifier l'étiquette. La question est, comment vous souvenez-vous de la rangée pour laquelle le commutateur est, alors? Une façon serait ceci:

- (void)didChangeStateForSwitch:(id)sender 
{ 
    NSIndexPath *indexPath = [myTableView indexPathForCell:[sender superview]]; 
    ... 
} 

Une autre possibilité est d'utiliser associated objects.

+0

votre réponse est correcte, c'était le problème. la solution n'a pas fonctionné pour moi cependant. J'ai créé l'UISwitch par programme. ça fonctionne bien maintenant. Merci. –

1

première fois lorsque vous chargez la cellule que vous prenez la vue avec l'étiquette 101 pour les lignes switch.Few après que vous configurez une nouvelle étiquette sur cet interrupteur et la prochaine fois vous essayez de prendre la vue avec l'étiquette 101, il n'existe pas. [newsSwitch setTag:indexPath.row]; supprimer cette ligne et essayez à nouveau

Vous pouvez obtenir le chemin d'index @DarkDust suggéré

- (void)didChangeStateForSwitch:(id)sender 
{ 
NSIndexPath *indexPath = [myTableView indexPathForCell:[sender superview]]; 
... 
} 
+0

la "[storage boolForKey: [NSString stringWithFormat: @" notification _% @ ", [nom de la notification]]]; n'est pas assez? –

+0

Cela m'est arrivé auparavant. Tout comme @wootage a dit que vous devriez garder vos états de commutation dans un tableau et le définir dans votre cellForRowAtIndexPath – Pancho

+0

Vous devez implémenter CustomTableViewCell et donner la balise uniq à chaque Switch, pour le résoudre dans didChangeStateForSwitch! –