2009-07-23 11 views
29

Necesito alguna guía para crear una UITableViewCell que tenga una imagen a la izquierda que se puede alternar. La imagen debe poder seleccionarse y actuar como un botón de alternar (casilla de verificación).Alternar imagen de casilla de verificación en UITableViewCell

Mis partes Estoy luchando con son:

  1. ¿Cómo puedo detectar toques en la imagen y manejar de manera diferente a los didSelectRowAtIndexPath?
  2. ¿Cómo cambio la imagen sin realizar [tableView reloadData]?

Ver la imagen de abajo para una muestra:

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

Gracias

+0

hola rein, ¿cómo se puede hacer esta imagen para su pregunta? ¿Hay algún software disponible para esto? – raaz

+0

¿Dónde obtiene el icono de la marca de verificación? –

+1

¿También puedo encontrar el ícono de marca de verificación desde donde obtuve? – Ralphleon

Respuesta

28

En realidad es bastante fácil.

Simplemente crea una nueva subclase de UIControl y ponlo todo allí (no es necesario un controlador por separado). Llamémoslo ToggleImageControl.

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

Cree un ToggleImageControl para cada celda y agréguelo en la posición adecuada.

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

Agregue un UIImageView para que contenga la imagen. Agregue un objetivo para el evento táctil.

- (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]; 

} 

Establezca la propiedad de la imagen de UIImageView para actualizar la imagen; eso disparará el redibujado sin efectos secundarios.

- (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]; 

} 

Obviamente tendrá que masajear algunas cosas. Probablemente quiera pasar los dos nombres de imagen para que sea más reutilizable, y también recomendaría especificar la cadena de nombre de notificación desde fuera del objeto también (suponiendo que esté utilizando el método de notificación)

+0

P.S. - De hecho, hago algunas cosas de esta manera - funciona. – Amagrammer

+0

Esto es genial! Gracias. Una pregunta, cuando se toca el control toggleImage, el toque no se borrará en el archivo didSelectRowAtIndexPath de UITableView. ¿Correcto? – rein

+0

No, el botón lo intercepta y evita que la célula lo vea. – Amagrammer

0

hago algo similar (protagonizada por uno de los favoritos) como este, pero creo que está exigiendo mucho de los pulgares de los usuarios de iPhone con la celda dirigiendo a las personas a otra vista. En primer lugar, verificaría la opción de divulgación de detalles en las celdas. Una de las opciones es un botón de flecha prefabricado que puede adjuntar. Tu llamada.

Es posible que pueda salirse con la suya atrapando el evento didSelectRowAtIndexPath y luego hacer alguna otra lógica en lugar de redirigir si el toque estaba en su casilla de verificación, aunque no sé cómo conseguiría el puesto. Esto significa que es posible que necesite encontrar una forma de familiarizarse con el evento táctil antes de llamar a la ruta didSelectRowAtIndex, que no estoy muy seguro de cómo hacerlo. ¿Ya has trabajado con toques de manejo de Began y similares?

+0

La captura de pantalla que he vinculado proviene de la aplicación Groceries de Sophiestication (http://www.sophiestication.com/groceries/). Sé que es posible porque esa aplicación lo hace y funciona bastante bien. He estado evitando la creación de mi propia clase UITableViewCell, hasta ahora me he salido con la puesta de vistas en contentView. Para implementar touchesBegan correctamente, creo que no tengo más remedio que crear mi propia clase UITableViewCell. ¿Cómo escribiste el código para destacar tus filas como favoritas? – rein

4

Así que el " ..obviamente necesita masajear algunas cosas ... "comentar significa" ... este código no funciona ... ".

Así

- (void) viewDidLoad 

debería ser

- (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; 
} 

Como - (void) viewDidLoad nunca se llama.

1

Hay una manera aún más FÁCIL de hacerlo, si anula touchesBegan: necesita hacer una instrucción if para decidir si está dentro de la proximidad de las marcas de verificación, si no es [super touchesBegan:touches withEvent:event] y actuará como si estuviera seleccionada.

6

Aquí hay una implementación del enfoque "anular touchesBegan:" que estoy usando que es simple y parece funcionar bien.

Solo incluya esta clase en su proyecto y cree y configure un TouchIconTableViewCell en lugar de una celda UITableView en su método 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 

Cada vez que se crea o reutilizar la célula, establece las touchIconDelegate y touchIconIndexPath propiedades. Cuando se toca su ícono, se invocará al delegado. Luego puedes actualizar el ícono o lo que sea.

+0

lo siento, pero ¿qué quiere decir exactamente con "establecer las propiedades touchIconDelegate y touchIconIndexPath"? – quantum

+0

Por ejemplo: // Crear celda TouchIconTableViewCell * cell = (TouchIconTableViewCell *) [tableView dequeueReusableCellWithIdentifier: ident]; if (cell == nil) cell = [[[TouchIconTableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: ident] autorelease]; cell.touchIconDelegate = self; cell.touchIconIndexPath = indexPath; – Archie

+0

Me gusta. Parecía un poco más simple que crear otro control para lanzar en mi celda de tabla personalizada. –

3

Parece que Apple ha subido "TableMultiSelect" como códigos de muestra en el Programa para desarrolladores de iOS desde 2011-10-12.

Este código permite la selección múltiple en modo de edición.

self.tableView.allowsMultipleSelectionDuringEditing = YES; 

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

A pesar de que sólo se puede utilizar a partir de IOS5.

Varias horas No pude encontrar este código de muestra en Stack Overflow, así que agregué esta información a esta publicación.

+0

Este es un código de muestra muy agradable. Gracias por traer a nuestra atención. – rein

Cuestiones relacionadas