2009-07-23 11 views
29

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

Mes pièces que je suis aux prises avec sont:

  1. Comment détecter les robinets sur l'image et les gérer différemment à didSelectRowAtIndexPath?
  2. Comment puis-je modifier l'image sans exécuter [tableView reloadData]?

Voir l'image ci-dessous pour un échantillon:

alt text http://img208.yfrog.com/img208/6119/screenshotkmr.png

Merci

+0

salut rein, comment pouvez-vous faire cette image pour votre question? Y at-il un logiciel disponible pour cela? – raaz

+0

Où obtenez-vous l'icône en forme de coche? –

+1

Puis-je également cogner d'où vous avez cette icône de coche? – Ralphleon

Répondre

28

C'est en fait assez facile.

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

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

Créez un ToggleImageControl pour chaque cellule et ajoutez-le à l'emplacement approprié.

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

Ajoutez un UIImageView pour contenir l'image. Ajoutez 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éfinissez la propriété d'image de UIImageView pour mettre à jour l'image; cela déclenchera le redessin 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]; 

} 

Vous aurez évidemment besoin de masser certaines choses. Vous voudrez probablement transmettre les deux noms d'image pour les rendre plus réutilisables, et je vous recommande également de spécifier la chaîne de nom de notification depuis l'extérieur de l'objet (en supposant que vous utilisez la méthode de notification.)

+0

P.S. - Je fais certaines choses de cette façon - ça marche. – Amagrammer

+0

C'est génial! Merci. Une question, lorsque le contrôle toggleImage est tapé, le tap ne sera pas envoyé au didSelectRowAtIndexPath de UITableViewControl. Correct? – rein

+0

Non, le bouton l'intercepte et l'empêche d'être vu par la cellule. – Amagrammer

0

je fais quelque chose de similaire (mettant en vedette un favori) comme ça, mais je pense que vous êtes exigeant beaucoup de les pouces des utilisateurs d'iPhone avec la cellule dirigeant les gens vers une autre vue. Tout d'abord, je voudrais vérifier l'option de divulgation de détail sur les cellules. Une des options est un bouton fléché prédéfini auquel vous pouvez attacher. Ton appel. Vous pourrez peut-être vous en sortir en attrapant l'événement didSelectRowAtIndexPath et ensuite en faisant une autre logique au lieu de rediriger si le toucher était sur votre case à cocher, bien que je ne sache pas comment vous obtiendriez la position. Cela signifie que vous devrez peut-être trouver un moyen de récupérer l'événement tactile avant d'appeler le chemin didSelectRowAtIndex, que je ne suis pas sûr de savoir comment faire. Avez-vous travaillé avec la manipulation des touchesBegan et similaires encore?

+0

La capture d'écran que j'ai liée provient de l'application Groceries de Sophiestication (http://www.sophiestication.com/groceries/). Je sais que c'est possible parce que cette application le fait et ça marche plutôt bien. J'ai évité de créer ma propre classe UITableViewCell - jusqu'à présent, je n'ai pas réussi à placer des vues dans contentView. Pour implémenter touchesBegan correctement, je pense que je n'ai pas d'autre choix que de créer ma propre classe UITableViewCell. Comment avez-vous écrit le code pour classer vos lignes comme favoris? – rein

4

..obécessairement besoin de masser des trucs .. "commentaire signifie" ... ce code ne fonctionne pas ... ".

Alors

- (void) viewDidLoad 

devrait être

- (id)initWithFrame:(CGRect)frame 
{ 
if (self = [super initWithFrame: frame]){ 
    normalImage = [UIImage imageNamed: @"toggleImageNormal.png"]; 
    selectedImage = [UIImage imageNamed: @"toggleImageSelected.png"]; 
    imageView = [[UIImageView alloc] initWithImage: normalImage]; 

// set imageView frame 
    [self addSubview: imageView]; 

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

return self; 
} 

Comme - (void) viewDidLoad ne sera jamais appelé.

1

Il existe un moyen encore plus FACILE de le faire, si vous surchargez touchesBegan: vous devez faire une instruction if pour décider si elle est dans la proximité des marques, si elle n'est pas [super touchesBegan:touches withEvent:event] et elle agira comme si elle était sélectionnée.

6

Voici une implémentation de l'approche "override touchesBegan:" que j'utilise qui est simple et qui semble bien fonctionner. Il suffit d'inclure cette classe dans votre projet et de créer et de configurer un TouchIconTableViewCell au lieu d'une cellule UITableView dans votre méthode tableView:cellForRowAtIndexPath:.

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 réutiliser la cellule, définissez les touchIconDelegate et touchIconIndexPath propriétés. Lorsque votre icône est touchée, le délégué sera appelé. Ensuite, vous pouvez mettre à jour l'icône ou quoi que ce soit.

+0

désolé mais que voulez-vous dire par "définir les propriétés touchIconDelegate et touchIconIndexPath"? – quantum

+0

Par exemple: // Créer une cellule TouchIconTableViewCell * cell = (TouchIconTableViewCell *) [tableView dequeueReusableCellWithIdentifier: ident]; if (cellule = 0) cellule = [[[TouchIconTableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: ident] autorelease]; cell.touchIconDelegate = self; cell.touchIconIndexPath = indexPath; – Archie

+0

J'aime ça. Semblait un peu plus simple que de créer un autre contrôle à jeter dans ma cellule de table personnalisée. –

3

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

La sélection multiple en mode édition peut être activée par ce code.

self.tableView.allowsMultipleSelectionDuringEditing = YES; 

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

Bien qu'il puisse être utilisé que de iOS5.

Plusieurs heures je ne pouvais pas trouver cet exemple de code dans Stack Overflow, donc j'ai ajouté cette information à ce post.

+0

Ceci est un très bon exemple de code. Merci de l'avoir porté à notre attention. – rein