2009-08-24 14 views
10

Ho un UISwitch all'interno di una UITableViewCell personalizzata (la sottoclasse di cui si chiama RootLabeledSwitchTableCell).UISwitch interno personalizzato UITableViewCell non disponibile

La cella contiene uno UILabel e UISwitch uno accanto all'altro.

Ho un @property chiamato keychainSwitch che punta allo switch all'interno di questa cella personalizzato:

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

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

@end 

A mio tavolo vista delegato, ho aggiunto un selettore che si chiama se lo stato interruttore è azionato:

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

Quindi questo selettore funziona correttamente:

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

Tuttavia, non posso utilizzare il metodo -setOn:animated: dell'istanza UISwitch per inizializzare suo stato iniziale:

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

Da test, self.keychainSwitch è nil che sta causando -setOn:animated di non fare nulla, ma posso ancora azionare l'interruttore e la dichiarazione NSLog stamperà correttamente i cambiamenti di stato degli interruttori, ad esempio:

[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 

c'è qualcosa che mi manca sull'impostazione self.keychainSwitch nel metodo UITableView delegato?

risposta

5

Ho fatto un po 'di tempo fa. Si dovrebbe cambiare il tuo selctor

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

E poi aggiornare il metodo per

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

Ora tempSwitch è l'interruttore che è stato modificato.

+1

Questo non ha funzionato sulla mia fine. Grazie per il suggerimento, però. –

+1

Non ha funzionato neanche qui. Ho ottenuto: [OptionsViewController toggleImage]: selettore non riconosciuto inviato all'istanza 0x4b305c0 '. Nota che chiamarlo senza il parametro ha funzionato bene (anche se ovviamente non sapevo quale interruttore lo stava chiamando!) – Julian

+1

Oops, ha funzionato. Assicurati di aggiungere l'azione di destinazione per includere i due punti nella tua chiamata di selezione! Questo funziona @selector (keychainOptionSwitched :), questo non @selector (keychainOptionSwitched). – Julian

0

Penso che quello che sta succedendo qui è che si sta tentando di richiamare l'operazione quando la cella è fuori dalla vista, quindi cosa sta succedendo è che la cella viene scaricata in quel momento quindi si sta ottenendo un nulla per l'interruttore portachiavi, una volta che viene visualizzato, non è più nulla da quando è stato ricaricato. Ma vedo che si sta assegnando l'interruttore in questo modo

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

E 'un riferimento al interruttore nella cella della tabella e non si sta mantenendo, così fa da quel nullo l'interruttore sta diventando in quanto, quando la cellula esce fuori vista viene scaricato e keychainSwitch sta diventando nullo come risultato e quindi anche il membro della tua classe sta diventando nullo. Si potrebbe desiderare di mantenere keychainSwitch e quindi quando si ricostruisce la tabella c ell ottenere il passaggio da portachiaviSwitch, o qualcosa del genere. Spero che questo aiuti

+0

self.keychainSwitch = [[(RootLabeledSwitchTableCell *) cell labeledSwitch] retain]; non funziona. –

+0

più probabilmente hai comunque la proprietà che conserva comunque ... cosa succede quando provi la riga sopra cita? – Daniel

+0

Inoltre, tutte le celle di visualizzazione tabella sono in vista quando chiamo il metodo -updateInterfaceState, inclusa la cella con l'istanza keychainSwitch. –

70

Ho passato anni a trafficare con UITableViewCells personalizzato con una semplice etichetta e l'ho acceso prima che scoprissi che potrei semplicemente aggiungere un UISwitch come vista accessoria. Probabilmente ne sei a conoscenza e vuoi la cella personalizzata per altri motivi, ma nel caso volessi menzionarlo!

A tale scopo, come segue (in -tableView: Metodo cellForRowAtIndexPath):

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

Il bit accessoryView si occupa anche del dimensionamento ed il posizionamento in modo che possiamo ottenere via con CGRectZero.

Sei quindi in grado di utilizzare l'evento di controllo del sistema e il metodo di Seton come segue (nota gettiamo come il puntatore UISwitch che noi sappiamo che è):

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

Speranza che aiuta!

+1

Sì, so del vista accessoria. Mi piacerebbe utilizzare una cella personalizzata in questo caso particolare, ma grazie! –

+11

[cella addSubview: mySwitch]; non è necessario cell.accessoryView conserva mySwitch. –

+0

Ti ho votato, ma un semplice up-votato non mi è sembrato abbastanza "grazie". Grazie! A volte sono così concentrato sul problema in questione, mi sono dimenticato di questi piccoli extra nel framework. –

Problemi correlati