2009-06-05 16 views
8

Ich habe eine benutzerdefinierte UIPickerView wo ich verwenden:Zwingende markierte Auswahl in UIPickerView

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

mit UILabels den Picker zu füllen. Gibt es eine Möglichkeit, das Verhalten beim Markieren der ausgewählten Zeile zu deaktivieren?

Ich denke, das ist eine Eigenschaft des zugrunde liegenden UITableViewCell inhärent in der UIPickerView und ich kann keinen Weg finden, es zu ändern.

Antwort

16

Sie müssen sicherstellen, dass Ihre benutzerdefinierte Ansicht die folgenden Eigenschaften hat:

  1. auf die gleichen Dimensionen bemessen werden muss, dass der UIPickerView auf Delegatmethoden Basis erwartet - pickerView:rowHeightForComponent: und pickerView:widthForComponent:. Die Standardhöhe ist 44, wenn Sie keine benutzerdefinierte Höhe angeben.
  2. Die Hintergrundfarbe muss [UIColor clearColor] sein.
  3. Die Ansicht muss alle Berührungen erfassen.

Die eine Gotcha wenn UILabel Instanzen als benutzerdefinierte Ansicht ist, dass UILabel defaults userInteractionEnabled-NO (UIView, auf der anderen Seite, defaults diese Eigenschaft auf YES).

Basierend auf diesen Anforderungen kann der Beispielcode aus Halle folgendermaßen umgeschrieben werden. In diesem Beispiel werden auch zuvor erstellte Ansichten, die für eine schnelle Bildlaufleistung benötigt werden, korrekt wiederverwendet.

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

Ich denke, man kann bei „showsSelectionIndicator“ Eigentum von UIPickerView aussehen wollen

+0

Der showSelectionIndicator ist verantwortlich für die Anzeige des blauen Balkens über dem Wert, der vom Picker zurückgegeben wird. Es hat leider nichts mit der zugrunde liegenden UITableViewCell-Struktur zu tun. – Jon

0

Ich bin mir nicht sicher, ob es eine einfache Möglichkeit ist die Auswahl Feedback zu entfernen, aber Sie können es vertuschen, wenn Sie den Hintergrund machen das Etiketts weiß und Größe es auf die gleichen Abmessungen wie das blaue Auswahlrechteck:

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

} 

Mit einer Breite von 316 deckt das Etikett alle außer einem Faserband von blau auf jeder Seite und bei 320 deckt sie vollständig die Auswahl Feedback, aber es fängt auch an, ein wenig von den äußeren Radverläufen abzudecken, die Sie stören können oder nicht.

12

Einstellen der userInteractionEnabled Eigenschaft UILabel zu YES behebt die Hervorhebung Problem, aber es sperrt auch die UIPickerView von Autoscrolling die Zeile auszuwählen, die berührt wurde.

Wenn Sie die Markierung Verhalten deaktivieren möchten, aber die UIPickerView ‚s Standard Autoscrolling Funktionalität zu erhalten, rufen Sie die setShowSelection Funktion in den UITableCell Instanzen im UIPickerView enthalten. Ein Weg, dies zu tun, ist die UILabel Klasse ähnlich den folgenden Unterklasse:

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 

Dann wo hatten Sie vorher eine Instanz von UILabel in pickerView:viewForRow:forComponent:reusingView: worden Rückkehr gibt eine Instanz von PickerViewLabel. Wenn Sie beispielsweise den Code Doug verwenden, würden Sie alle Fälle von "UILabel" durch "PickerViewLabel" ersetzen. Denken Sie daran, die pickerRowLabel.userInteractionEnabled = YES; Linie zu entfernen.

+0

Hallo Christine, ich habe den gleichen obigen Code implementiert, aber immer noch blaue Auswahl kommt an beiden Enden der ausgewählten Zeile. Wenn ich versuche, den Code zu debuggen, habe ich festgestellt, dass didMoveToSuperview nirgendwo aufgerufen wird. Kannst du mir helfen? Vielen Dank. – engineer

+0

Hey Shailesh, Es ist schwer zu sagen, dass du deinen Code nicht siehst, aber ich habe ein paar Ideen, warum er nicht aufgerufen wird. 'didMoveToSuperview' ist eine Funktion von UIView, die automatisch aufgerufen wird, wenn eine UIView einer Ansicht hinzugefügt oder daraus entfernt wird. Wird Ihre benutzerdefinierte Ansicht definitiv dem Bildschirm hinzugefügt? Wenn Sie einen schnellen Test durchführen und eine Instanz Ihrer Klasse als Unteransicht der Ansicht eines UIViewControllers hinzufügen, wird dann 'didMoveToSuperview' aufgerufen? Wenn nicht, würde ich vermuten, dass Sie irgendwo in der Funktionsdeklaration einen Tippfehler haben. – Christine

+0

great .... danke viel .. du hast mir das Leben gerettet und viel Zeit –