2009-08-24 19 views
10

Tengo un UISwitch dentro de un UITableViewCell personalizado (la subclase de la cual llamo RootLabeledSwitchTableCell).UISwitch dentro de la UITableViewCell personalizada no disponible

La celda contiene un UILabel y UISwitch uno al lado del otro.

Tengo un @property llamada keychainSwitch que apunta hacia el interruptor dentro de esta celda personalizado:

@interface RootLabeledSwitchTableCell : UITableViewCell { 
    IBOutlet UILabel *textLabel; 
    IBOutlet UISwitch *labeledSwitch; 
} 

@property (nonatomic, retain) IBOutlet UILabel *textLabel; 
@property (nonatomic, retain) IBOutlet UISwitch *labeledSwitch; 

@end 

En mi mesa con vista al delegado, he añadido un selector que se llama si se invierte el estado del interruptor:

- (UITableViewCell *) tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSString *CellIdentifier = [NSString stringWithFormat: @"%d:%d", [indexPath indexAtPosition:0], [indexPath indexAtPosition:1]]; 
    UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     switch (indexPath.section) { 
     case(kMyFirstSection): { 
      switch (indexPath.row) { 
       case(kMyFirstSectionFirstRow) { 
        [cellOwner loadMyNibFile:@"RootLabeledSwitchTableCell"]; 
        cell = (RootLabeledSwitchTableCell *)cellOwner.cell; 
        self.keychainSwitch = [(RootLabeledSwitchTableCell *)cell labeledSwitch]; 
        [self.keychainSwitch addTarget:self action:@selector(keychainOptionSwitched) forControlEvents:UIControlEventValueChanged]; 
        break; 
       } 
       // ... 
      } 
     } 
     // ... 
    } 
} 

Así que este selector funciona correctamente:

- (void) keychainOptionSwitched { 
    NSLog(@"Switched keychain option from %d to %d", ![self.keychainSwitch isOn], [self.keychainSwitch isOn]); 
} 

Sin embargo, no puede utilizar el método de la UISwitch de ejemplo -setOn:animated: para inicializar su estado inicial:

- (void) updateInterfaceState { 
    BOOL isFirstTimeRun = [[[NSUserDefaults standardUserDefaults] objectForKey:kIsFirstTimeRunKey] boolValue]; 
    if (isFirstTimeRun) { 
     [self.keychainSwitch setOn:NO animated:NO]; 
    } 
} 

De las pruebas, self.keychainSwitch es nil que está causando -setOn:animated no hacer nada, pero todavía se puede accionar el interruptor y la declaración NSLog imprimirá correctamente los cambios de estado del interruptor, por ejemplo:

[Session started at 2009-08-24 07:04:56 -0700.] 
2009-08-24 07:04:58.489 MyApp[29868:20b] keychain switch is: nil 
2009-08-24 07:05:00.641 MyApp[29868:20b] Switched keychain option from 1 to 0 
2009-08-24 07:05:01.536 MyApp[29868:20b] Switched keychain option from 0 to 1 
2009-08-24 07:05:02.928 MyApp[29868:20b] Switched keychain option from 1 to 0 

¿hay algo que me falta acerca de la configuración self.keychainSwitch en el método UITableView delegado?

Respuesta

5

Hace esto hace un tiempo. Debe cambiar su selctor

[self.keychainSwitch addTarget:self action:@selector(keychainOptionSwitched:) forControlEvents:UIControlEventValueChanged]; 

Y luego actualizar su método para

-(void) keychainOptionSwitched:(id)sender { 
UISwitch *tempSwitch = (UISwitch *)sender; 
} 

Ahora tempSwitch es el interruptor que se ha cambiado.

+1

Esto no funcionó en mi extremo. Gracias por la sugerencia, sin embargo. –

+1

No funcionó aquí tampoco. Obtuve: [OptionsViewController toggleImage]: selector no reconocido enviado a la instancia 0x4b305c0 '. Tenga en cuenta que llamarlo sin el parámetro funcionaba bien (¡aunque obviamente no podía saber qué interruptor lo estaba llamando!) – Julian

+1

Vaya, lo hice funcionar. ¡Asegúrese de agregar la acción objetivo para incluir los dos puntos en su llamada al selector! Esto funciona @selector (keychainOptionSwitched :), esto no @selector (keychainOptionSwitched). – Julian

0

Creo que lo que está sucediendo aquí es que estás tratando de invocar la operación cuando la celda está fuera de la vista, entonces lo que sucede es que la celda está descargada en ese momento, por lo que obtienes nada para el interruptor de llavero. una vez que sale a la luz, ya no es nulo desde que se recargó. Pero veo que está asignando el interruptor al igual que

self.keychainSwitch = [(RootLabeledSwitchTableCell *)cell labeledSwitch]; 

Es una referencia al interruptor en la celda de la tabla y no se está reteniendo él, así que tiene desde que nil el interruptor está convirtiendo ya que, cuando la célula sale de la vista y está descargado y keychainSwitch se está volviendo nulo como resultado y por lo tanto, su miembro de la clase también se está volviendo nulo. Es posible que desee conservar keychainSwitch y luego, al reconstruir su tabla, obtenga el interruptor de keychainSwitch, o algo por el estilo. Espero que esto ayude

+0

self.keychainSwitch = [[(RootLabeledSwitchTableCell *) celda etiquetada Interruptor] retener]; No funciona. –

+0

además, probablemente tenga la propiedad retenida de todos modos ... ¿qué ocurre cuando prueba la línea anterior, sin embargo? – Daniel

+0

Además, todas las celdas de la vista de tabla están a la vista cuando llamo al método -updateInterfaceState, incluida la celda con la instancia de keychainSwitch. –

70

Pasé mucho tiempo jugueteando con UITableViewCells personalizadas con una etiqueta simple y lo enciendo antes de descubrir que solo podía agregar un UISwitch como una vista accesoria. Probablemente ya sepa esto y quiera la celda personalizada por otras razones, ¡pero por si acaso quisiera mencionar esto!

Esto se hace de la siguiente manera (en el -tableView: Método cellForRowAtIndexPath):

UISwitch *mySwitch = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease]; 
cell.accessoryView = mySwitch; 

El bit accessoryView también se encarga del tamaño y ubicación para que podamos salir con CGRectZero.

Usted es entonces capaz de utilizar el evento de control del sistema y método de Seton de la siguiente manera (tenga en cuenta que proyectarlo como el puntero UISwitch que sabemos es):

[(UISwitch *)cell.accessoryView setOn:YES]; // Or NO, obviously! 
[(UISwitch *)cell.accessoryView addTarget:self action:@selector(mySelector) 
    forControlEvents:UIControlEventValueChanged]; 

Espero que ayude!

+1

Sí, sé de la vista de accesorios. Me gustaría utilizar una celda personalizada en este caso en particular, ¡pero gracias! –

+11

[cell addSubview: mySwitch]; no es necesario cell.accessoryView conserva mySwitch. –

+0

Yo voté por ti, pero una simple votación positiva no parecía lo suficientemente "gracias". ¡Gracias! A veces me enfoco tanto en el problema, me olvidé de estos pequeños extras en el marco. –

Cuestiones relacionadas