2009-06-05 15 views
8

Ho un personalizzato UIPickerView dove io uso:Override evidenziato selezione nella UIPickerView

-(UIView *)pickerView:(UIPickerView *)pickerView 
     viewForRow:(NSInteger)row 
    forComponent:(NSInteger)component 
     reusingView:(UIView *)view 

per popolare il selettore con UILabels. C'è un modo per disabilitare il comportamento di evidenziare la riga selezionata quando viene toccato?

Penso che questa sia una proprietà del sottostante UITableViewCell inerente allo UIPickerView e non riesca a trovare un modo per cambiarlo.

risposta

16

È necessario assicurarsi che la visualizzazione personalizzata ha le seguenti proprietà:

  1. Ha bisogno di essere dimensionato per le stesse dimensioni che l'UIPickerView aspetta, sulla base di metodi delegato - pickerView:rowHeightForComponent: e pickerView:widthForComponent:. L'altezza predefinita è 44 se non si specifica un'altezza personalizzata.
  2. Il colore di sfondo deve essere [UIColor clearColor].
  3. La vista deve catturare tutti i tocchi.

Quello Gotcha quando si utilizza UILabel casi come la visualizzazione personalizzata è che UILabel default userInteractionEnabled-NO (UIView, d'altra parte, per default questa proprietà per YES).

In base a questi requisiti, il codice di esempio da Halle può essere riscritta come segue. Questo esempio riutilizza correttamente anche le viste create in precedenza, necessarie per prestazioni di scorrimento veloci.

- (UIView *)pickerView:(UIPickerView *)pickerView 
      viewForRow:(NSInteger)row 
      forComponent:(NSInteger)component 
      reusingView:(UIView *)view { 

    UILabel *pickerRowLabel = (UILabel *)view; 
    if (pickerRowLabel == nil) { 
    // Rule 1: width and height match what the picker view expects. 
    //   Change as needed. 
    CGRect frame = CGRectMake(0.0, 0.0, 320, 44); 
    pickerRowLabel = [[[UILabel alloc] initWithFrame:frame] autorelease]; 
    // Rule 2: background color is clear. The view is positioned over 
    //   the UIPickerView chrome. 
    pickerRowLabel.backgroundColor = [UIColor clearColor]; 
    // Rule 3: view must capture all touches otherwise the cell will highlight, 
    //   because the picker view uses a UITableView in its implementation. 
    pickerRowLabel.userInteractionEnabled = YES; 
    } 
    pickerRowLabel.text = [pickerDataArray objectAtIndex:row]; 

    return pickerRowLabel; 
} 
0

Credo che si consiglia di guardare "showsSelectionIndicator" di proprietà di UIPickerView

+0

ShowSelectionIndicator è responsabile della visualizzazione della barra blu sul valore che verrà restituito dal selettore. Sfortunatamente non ha nulla a che fare con la struttura di UITableViewCell sottostante. – Jon

0

non sono sicuro se c'è un modo semplice per rimuovere le valutazioni di selezione, ma si può coprire fino se fate lo sfondo dell'etichetta bianca e dimensioni per le stesse dimensioni della selezione rettangolo blu:

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view { 

    UILabel *pickerRowLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 316, 40)]; 
    pickerRowLabel.backgroundColor = [UIColor whiteColor]; 
    pickerRowLabel.text = [pickerDataArray objectAtIndex:row]; 
    [self.view addSubview:pickerRowLabel]; 

    return pickerRowLabel; 

} 

Con una larghezza di 316 dell'etichetta copre tutto ma una scheggia di blu su ciascun lato, e al 320 copre completamente la selezione feedback ma inizia anche a coprire un po 'i gradienti della ruota esterna, che possono o non possono infastidirti.

12

L'impostazione della proprietà userInteractionEnabled di UILabel a YES risolve il problema mettendo in evidenza, ma disattiva anche il UIPickerView da scorrimento automatico per selezionare la riga che è stato toccato.

Se si desidera disattivare il comportamento evidenziazione, ma mantenere la funzionalità predefinita scorrimento automatico 's il UIPickerView, chiamare la funzione setShowSelection nelle UITableCell casi contenuti nel UIPickerView. Un modo per farlo è quello di creare una sottoclasse della classe UILabel simile al seguente:

PickerViewLabel.h -

#import <UIKit/UIKit.h> 

@interface PickerViewLabel:UILabel 
{ 
} 

@end 

PickerViewLabel.m -

#import "PickerViewLabel.h" 

@implementation PickerViewLabel 

- (void)didMoveToSuperview 
{ 
if ([[self superview] respondsToSelector:@selector(setShowSelection:)]) 
{ 
    [[self superview] performSelector:@selector(setShowSelection:) withObject:NO]; 
} 
} 

@end 

Allora, dove è stata precedentemente restituendo un'istanza di UILabel in pickerView:viewForRow:forComponent:reusingView:, restituire un'istanza di PickerViewLabel. Ad esempio, utilizzando il codice da Doug, sostituire tutti i casi di "UILabel" con "PickerViewLabel". Basta ricordare di rimuovere la riga pickerRowLabel.userInteractionEnabled = YES;.

+0

Ciao Christine, ho implementato lo stesso codice sopra, ma la selezione del blu arriva sempre alla fine della riga selezionata. Quando provo a eseguire il debug del codice, ho scoperto che MoveToSuperview non è stato chiamato da nessuna parte. Mi potete aiutare? Grazie. – engineer

+0

Hey Shailesh, è difficile dire di non vedere il tuo codice, ma ho qualche idea sul motivo per cui non sarebbe stato chiamato. 'didMoveToSuperview' è una funzione di UIView che viene richiamato automaticamente ogni volta che un UIView viene aggiunto o rimosso da una vista. La tua visualizzazione personalizzata viene sicuramente aggiunta allo schermo? Se si esegue un test rapido e si aggiunge un'istanza della classe come sottoview della vista di UIViewController, viene visualizzato "didMoveToSuperview" in quel momento? In caso contrario, suppongo che tu abbia un errore di battitura da qualche parte nella dichiarazione di funzione. – Christine

+0

fantastico .... grazie mille .. mi hai salvato la vita e un sacco di tempo –