29 votes

Basculer l'image de la case à cocher dans UITableViewCell

J'ai besoin de quelques conseils sur la création d'un UITableViewCell qui a une image sur la gauche qui peut être activée. L'image doit être tappable et d'agir comme un interrupteur à bascule (case à cocher).

Mes pièces je suis aux prises avec sont:

  1. Comment puis-je détecter les robinets sur l'image et la traiter différemment didSelectRowAtIndexPath?
  2. Comment puis-je changer l'image sans procéder à un [tableView reloadData]?

Voir l'image ci-dessous pour un exemple:

alt text

Merci

28voto

Amagrammer Points 5064

C'est en fait assez facile.

Il suffit de créer une nouvelle sous-classe de UIControl et tout mettre dedans (pas besoin d'un contrôleur séparé.) Appelons ça de la ToggleImageControl.

@interface ToggleImageControl : UIControl
{
   BOOL selected;
   UIImageView *imageView;
   UIImage *normalImage;
   UIImage *selectedImage;
}

Créer un ToggleImageControl pour chaque cellule, et l'ajouter à la position appropriée.

ToggleImageControl *toggleControl = [[ToggleImageControl alloc] initWithFrame: <frame>];
toggleControl.tag = indexPath.row;  // for reference in notifications.
[cell.contentView addSubview: toggleControl];

Ajouter une UIImageView pour contenir l'image. Ajouter une cible pour l'événement tactile.

- (void) viewDidLoad
{
   normalImage = [UIImage imageNamed: @"normal.png"];
   selectedImage = [UIImage imageNamed: @"selected.png"];
   imageView = [[UIImageView alloc] initWithImage: normalImage];
   // set imageView frame
   [self.view addSubview: imageView];

[self addTarget: self action: @selector(toggleImage) forControlEvents: UIControlEventTouchUpInside];

}

Définir la UIImageView l'image de la propriété pour mettre à jour l'image, qui va déclencher le redessiner sans effets secondaires.

- (void) toggleImage
{
   selected = !selected;
   imageView.image = (selected ? selectedImage : normalImage); 

   // Use NSNotification or other method to notify data model about state change.
   // Notification example:
   NSDictionary *dict = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: self.tag forKey: @"CellCheckToggled"];
   [[NSNotificationCenter defaultCenter] postNotificationName: @"CellCheckToggled" object: self userInfo: dict];

}

Il vous faudra bien évidemment pour masser certaines choses. Vous voulez probablement passer dans les deux noms d'images pour le rendre plus réutilisable, et aussi j'avais recommandons de spécifier le nom de notification de la chaîne de l'extérieur de l'objet (en supposant que vous êtes à l'aide de la méthode de notification.)

6voto

Archie Points 2742

Voici une mise en œuvre de la "remplacer touchesBegan:" approche, je suis en utilisant ce qui est simple et semble bien fonctionner.

Il suffit d'inclure cette classe dans votre projet et de créer et de configurer un TouchIconTableViewCell au lieu de UITableView de cellules dans votre tableView:cellForRowAtIndexPath: méthode.

TouchIconTableViewCell.h:

#import <UIKit/UIKit.h>

@class TouchIconTableViewCell;

@protocol TouchIconTableViewCellDelegate<NSObject>

@required
- (void)tableViewCellIconTouched:(TouchIconTableViewCell *)cell indexPath:(NSIndexPath *)indexPath;

@end

@interface TouchIconTableViewCell : UITableViewCell {
    id<TouchIconTableViewCellDelegate> touchIconDelegate;       // note: not retained
    NSIndexPath *touchIconIndexPath;
}

@property (nonatomic, assign) id<TouchIconTableViewCellDelegate> touchIconDelegate;
@property (nonatomic, retain) NSIndexPath *touchIconIndexPath;

@end

TouchIconTableViewCell.m:

#import "TouchIconTableViewCell.h"

@implementation TouchIconTableViewCell

@synthesize touchIconDelegate;
@synthesize touchIconIndexPath;

- (void)dealloc {
    [touchIconIndexPath release];
    [super dealloc];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint location = [((UITouch *)[touches anyObject]) locationInView:self];
    if (CGRectContainsPoint(self.imageView.frame, location)) {
        [self.touchIconDelegate tableViewCellIconTouched:self indexPath:self.touchIconIndexPath];
        return;
    }
    [super touchesBegan:touches withEvent:event];
}

@end

Chaque fois que vous créez ou la ré-utilisation de la cellule, l'ensemble de l' touchIconDelegate et touchIconIndexPath propriétés. Lorsque votre icône est touché, le délégué sera invoquée. Ensuite, vous pouvez mettre à jour l'icône ou quoi que ce soit.

3voto

tokentoken Points 344

Il semble que Apple téléchargé "TableMultiSelect" comme des exemples de codes sur iOS Developer Program depuis 2011-10-12.

La sélection Multiple dans l'edit mode peut être activé par le présent code.

self.tableView.allowsMultipleSelectionDuringEditing = YES;

http://developer.apple.com/library/ios/#samplecode/TableMultiSelect/Introduction/Intro.html

Bien qu'il peut être utilisé uniquement à partir de iOS5.

Plusieurs heures je ne pouvais pas trouver cet exemple de code dans le Débordement de la Pile, j'ai donc ajouté cette info à ce post.

1voto

Yakattak Points 786

Il y a un moyen encore PLUS FACILE de le faire, si vous remplacez les touchesBegan: vous devez faire une instruction if pour décider si elle se trouve à proximité des coches, si elle n'appelle pas [super touchesBegan:touches withEvent:event] et elle agira comme si elle était choisi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X