2009-04-25 14 views
18

Mam UIPickerView na moim UIView wraz z UITextField. Pozwalam użytkownikowi wybrać wartość z selektora lub wprowadzić niestandardową wartość w polu tekstowym.UIPickerView - wybór pierwszego rzędu nie wywołuje didSelectRow

Gdy użytkownik wybierze dowolną opcję z selektora, wartości zmiennych zostaną zmienione w porządku (w metodzie pickerView:didSelectRow:inComponent:). Ale jeśli użytkownik nie wybierze żadnej wartości w selektorze (bo chce wybrać pierwszą opcję, która jest już wybrana), ta metoda nie zostanie wywołana, a wybór nie zostanie odzwierciedlony w zmiennej.

Próbowałem ustawić domyślną wartość zmiennej w pierwszej opcji w selektorze. Ale w takim przypadku, gdy użytkownik edytuje pole tekstowe, zmienna będzie zawierała tekst pola tekstowego. Teraz, jeśli użytkownik zdecyduje się ponownie wybrać pierwszą wartość, nowa wartość nie zostanie odzwierciedlona w zmiennej.

Jak mogę to przezwyciężyć? Dzięki.

Oto odpowiedni kod

w moim viewDidLoad mam to oświadczenie, aby ustawić selectText do pierwszej opcji z próbnika domyślnie

[self setSelectText:[myArray objectAtIndex:0]]; 

textFieldShouldReturn

- (BOOL)textFieldShouldReturn:(UITextField *)txtField{ 
    [txtField resignFirstResponder]; 
    [self setSelectText:txtField.text]; 
    return YES; 
} 

PickerViewDelegate użytkownika didSelectRow

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 
{ 
    // report the selection to the UI label 
    [self setSelectText:[myArray objectAtIndex:[pickerView selectedRowInComponent:0]]]; 
} 

Problem pojawia się, gdy użytkownik edytuje tekst, a następnie decyduje, że mimo wszystko chce wykorzystać pierwszą wartość próbnika. W takim przypadku odłożą klawiaturę i klikną pierwszą opcję selektora (który jest już wybrany). Ta akcja nie wywołuje didSelectRow, więc wartość selectText nie jest zmieniana.

Aby użytkownik mógł zmienić wartość selectText, musi najpierw wybrać inną wartość z selektora, a następnie wybrać pierwszy wiersz.

+0

Jeśli możesz, opublikuj część kodu związaną z tym problemem. Pomoże to w rozwiązywaniu problemów. –

Odpowiedz

25

Zamiast za każdym razem „pchanie” wartość kompletacji dokonać wyboru z tym kodem:

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 

należy „wyciągnąć go”, gdy użytkownik kliknie przycisk (lub innego zdarzenia używasz) przy użyciu coś podobnego do:

- (void)myAction:(id)sender 
{ 

    NSInteger row = [myPicker selectedRowInComponent:0]; 
    selectedText = [myArray objectAtIndex:(NSUInteger)row]; 


} 

zgaszenia tekst: Klasa UITextField zapewnia wbudowany przycisk kasowania aktualnego tekstu. Więc jeśli użytkownik nie chce tego tekstu, może go odrzucić.

myTextField.clearButtonMode = UITextFieldViewModeAlways; 

Więc w skrypcie, można sprawdzić, czy TextField ma wartość, jeśli to ma wartość u używać TextField, jeśli nie ma wartości, można wyciągnąć informacje z Picker.

+0

Dzięki. Problem polega na tym, że użytkownik ma możliwość określenia wartości niestandardowej w polu tekstowym. Istnieje więc możliwość, że użytkownik wprowadzi jakiś tekst. Jeśli zrobię to, co zasugerowałeś, każda wartość wprowadzona przez użytkownika zostanie zignorowana. – lostInTransit

+1

Klasa UITextField zawiera również wbudowany przycisk do czyszczenia bieżącego tekstu. Więc jeśli użytkownik nie chce tego tekstu, może go odrzucić. myTextField.clearButtonMode = UITextFieldViewModeAlways; –

+0

Zaktualizowałem odpowiedź. –

2

Czy można programowo wybrać wiersz zaraz po utworzeniu UIPickerView?

int firstRow = 0; 
int firstOptionIndex = 0; 
[myPickerView selectRow:firstRow inComponent:firstOptionIndex animated:NO]; 

Ostatni wiersz wywoła metodę delegata pickerView:didSelectRow:inComponent.

Innymi słowy, powinno to ustawić wartość zmiennej, gdziekolwiek ją przechowujesz (NSArray? Nie jest jasne).

+0

To by zrobiło. Załóżmy jednak, że użytkownik decyduje się wprowadzić niestandardową wartość w polu tekstowym. A potem decyduje, że mimo wszystko chce użyć 1. wartości w selektorze. Więc teraz selectText ma wartość wprowadzoną w polu tekstowym. Użytkownik po prostu klika pierwszy wiersz myśląc, że zastąpi wartość wprowadzoną w polu tekstowym. Ale tak się nie stało, ponieważ program nie wiedziałby, że użytkownik stuknął w pierwszą opcję. – lostInTransit

+0

To dotykając pierwszego wiersza widoku próbnika nie generuje zdarzenia wyboru, może to być po prostu "niedociągnięcie" z projektem UIPickerView, ponieważ jest ono potrzebne do działania, ale niekoniecznie jest to problem z samym UITextField. Możesz rozważyć zgłoszenie ulepszenia funkcji do UIPickerView w http://bugreporter.apple.com. –

+0

Widzę inne zachowanie. Moja metoda delegatów nie uruchamia się, gdy programowo poruszam selektorem podczas opisywania. Wystrzeliwuje się zgodnie z oczekiwaniami, jeśli faktycznie przesuję selektor za pomocą interfejsu użytkownika. To ma dla mnie sens, że delegat nie wystrzeli. Ponieważ programowo przesuwam selektor, wiem, że został przeniesiony, więc mogę obsłużyć wszelkie wymagane aktualizacje. – Scooter

2
-(void)textFieldDidBeginEditing:(UITextField *)textField 
{ 
    // Only for the text field with the picker 
    if (textField == self.yourTextField && [textField length]!=0) 
    { 
     // Select the first row programmatically 
     [self.categoriesPicker selectRow:0 inComponent:0 animated:YES]; 
     // The delegate method isn't called if the row is selected programmatically 
     [self pickerView:self.categoriesPicker didSelectRow:0 inComponent:0]; 
    } 



} 

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 
{ 
    //Do all the stuff to populate the TextField 
} 
+0

wymuszone połączenie z delegatem wykonało zadanie –

0

Aby przezwyciężyć didSelectRow nie uzyskiwanie nazwie w UIPickerView gdy użytkownik wybiera pierwszą pozycję na liście, można użyć UITapGestureRecognizer. (Przykład kodu w Swift)

self.txtTransType = self.makeTextField(self.transType, placeHolder: "Check-in or Check-out") 
self.txtTransType?.addTarget(self, action: "txtTransTypeEditing:", forControlEvents: UIControlEvents.EditingDidBegin) 

func makeTextField(text: String?, placeHolder: String) -> UITextField { 
    var textField = UITextField(frame: CGRect(x: 140, y: 0, width: 220.00, height: 40.00)); 
    textField.placeholder = placeHolder 
    textField.text = text 
    textField.borderStyle = UITextBorderStyle.Line 
    textField.secureTextEntry = false; 
    textField.delegate = self 
    return textField 
} 

func txtTransTypeEditing(sender: UITextField) { 
    var ttPickerView:UIPickerView = UIPickerView() 
    ttPickerView.dataSource = self 
    ttPickerView.delegate = self 
    sender.inputView = ttPickerView 

    let recognizer = UITapGestureRecognizer(target: self, action:Selector("handleTransTypePickerTap:")) 
    recognizer.delegate = self 
    ttPickerView.addGestureRecognizer(recognizer) 
} 

func handleTransTypePickerTap(recognizer: UITapGestureRecognizer) { 
    let ttPickerView = recognizer.view as! UIPickerView 
    let row = ttPickerView.selectedRowInComponent(0) 
    self.txtTransType!.text = self.transTypeData[row] 
} 

Użyj poniższy link UIGestureRecognizer Tutorial: Getting Started dostać kranu rozpoznawania do pracy (trzeba dodać UIGestureRecognizerDelegate) i podany kod

class TransactionViewController: UIViewController, UITextFieldDelegate,UIPickerViewDataSource,UIPickerViewDelegate, UIGestureRecognizerDelegate { } 

func gestureRecognizer(UIGestureRecognizer, 
    shouldRecognizeSimultaneouslyWithGestureRecognizer:UIGestureRecognizer) -> Bool { 
     return true 
} 
2

można bezpośrednio wywołać metodę której przekazano jak

picker.delegate?.pickerView?(picker, didSelectRow: 0, inComponent: 0) 
Powiązane problemy