2009-04-25 2 views
18

Ich habe eine UIPickerView auf meinem UIView zusammen mit einem UITextField. Ich lasse den Benutzer einen Wert aus der Auswahl auswählen oder einen benutzerdefinierten Wert in das Textfeld eingeben.UIPickerView - erste Zeile Auswahl ruft nicht didSelectRow

Wenn der Benutzer eine Option aus der Auswahl auswählt, werden die Variablenwerte (in der pickerView:didSelectRow:inComponent:) Methode in Ordnung geändert. Wenn der Benutzer jedoch keinen Wert für die Auswahl auswählt (weil er die erste Option auswählen möchte, die bereits ausgewählt ist), wird diese Methode nicht aufgerufen und die Auswahl wird nicht in der Variablen wiedergegeben.

Ich habe versucht, den Standardwert der Variablen auf die erste Option in der Auswahl festzulegen. Aber in diesem Fall, wenn der Benutzer das Textfeld bearbeitet, hat die Variable den Text des Textfelds. Wenn der Benutzer nun entscheidet, den ersten Wert erneut auszuwählen, wird der neue Wert nicht in der Variablen wiedergegeben.

Wie kann ich das überwinden? Vielen Dank.

Hier ist der entsprechende Code

In meinem viewDidLoad Ich habe diese Aussage die selectText auf erste Option des Pickers durch Standard festlegen

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

textFieldShouldReturn

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

PickerViewDelegate des 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]]]; 
} 

Das Problem tritt auf, wenn der Benutzer den Text bearbeitet und dann entscheidet er sich schließlich will der erste Wert des Picker verwenden. In diesem Fall werden sie die Tastatur verwerfen und auf die erste Option der Auswahl klicken (die bereits ausgewählt ist). Diese Aktion ruft didSelectRow nicht auf und so wird der Wert von SelectText nicht geändert.

Damit der Benutzer den Wert selectText ändern kann, muss er zuerst einen anderen Wert aus der Auswahl auswählen und dann die erste Zeile auswählen.

+0

Wenn Sie können, bitte posten Sie einige Ihrer Code, wie es zu diesem Problem betrifft. Dies hilft bei der Fehlerbehebung. –

Antwort

25

Statt den Wert des Picker jedes Mal, wenn Sie eine Auswahl mit diesem Code machen „Schieben“:

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

sollten Sie „ziehen“, wenn der Benutzer klickt auf die Schaltfläche (oder ein anderes Ereignis, das Sie verwenden Verwendung) etwas ähnliches wie:

- (void)myAction:(id)sender 
{ 

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


} 

für den Text Löschen: die UITextField-Klasse stellt eine integrierte Schaltfläche für den aktuellen Text zu löschen. Wenn der Benutzer diesen Text also nicht möchte, kann er ihn löschen.

myTextField.clearButtonMode = UITextFieldViewModeAlways; 

So im Skript, werden Sie prüfen, ob die TextField einen Wert hat, wenn es einen Wert u die TextField- verwenden hat, wenn es keinen Wert hat, ziehen Sie die Informationen aus den Picker.

+0

Danke. Das Problem hierbei ist jedoch, dass der Benutzer die Möglichkeit hat, einen benutzerdefinierten Wert in einem Textfeld anzugeben. Es besteht also die Möglichkeit, dass der Benutzer einen Text eingibt. Wenn ich jetzt das mache, was Sie vorgeschlagen haben, wird jeder Wert, den der Benutzer eingibt, ignoriert. – lostInTransit

+1

Die UITextField-Klasse bietet auch eine integrierte Schaltfläche zum Löschen des aktuellen Textes. Wenn der Benutzer diesen Text also nicht möchte, kann er ihn löschen. myTextField.clearButtonMode = UITextFieldViewModeAlways; –

+0

Ich habe die Antwort aktualisiert. –

2

Können Sie programmgesteuert eine Zeile direkt nach der Instanziierung des UIPickerViews auswählen?

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

Diese letzte Zeile löst Ihre pickerView:didSelectRow:inComponent Delegiertenmethode aus.

Mit anderen Worten, das sollte den Wert der Variablen festlegen, wo auch immer Sie es speichern (NSArray? Nicht klar).

+0

Das würde tun. Angenommen, der Benutzer entscheidet, einen benutzerdefinierten Wert in das Textfeld einzugeben. Und dann entscheidet er, dass er doch den 1. Wert im Picker verwenden will. Nun hat selectText den Wert, der im Textfeld eingegeben wurde. Und der Benutzer klickt einfach auf die erste Zeile und denkt, er überschreibt den Wert, der in das Textfeld eingegeben wurde. Aber das würde nicht passieren, weil das Programm nicht wissen würde, dass der Benutzer auf die erste Option geklickt hat. – lostInTransit

+0

Dass das Berühren der ersten Zeile einer Auswahlansicht nicht das Auswahlereignis für Sie generiert, kann einfach ein "Manko" mit dem UIPickerView-Design sein, wenn Sie es benötigen, aber es ist nicht unbedingt ein Problem mit UITextField selbst. Sie könnten eine Funktionserweiterung für UIPickerView in http://bugreporter.apple.com einreichen. –

+0

Ich sehe ein anderes Verhalten. Meine Delegate-Methode wird nicht ausgelöst, wenn ich die Auswahl programmgesteuert bei der Beschreibung verschiebe. Es wird wie erwartet ausgelöst, wenn ich den Picker mithilfe der Benutzeroberfläche tatsächlich verschiebe. Es macht Sinn für mich, dass der Delegierte nicht feuern würde. Da ich den Picker programmgesteuert verschiebe, weiß ich, dass er verschoben wurde, sodass ich dann alle erforderlichen Updates verarbeiten kann. – 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

der erzwungene Aufruf an den Delegaten hat die Aufgabe erfüllt –

0

Um die didSelectRow zu überwinden nicht in der UIPickerView genannt wird, wenn der Benutzer das erste Element in der Liste ausgewählt haben, können Sie UITapGestureRecognizer verwenden. (Code-Beispiel in 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] 
} 

Verwenden Sie den folgenden Link UIGestureRecognizer Tutorial: Getting Started Hahn Erkenner an die Arbeit (müssen UIGestureRecognizerDelegate hinzufügen) und Code folgenden

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

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

Sie direkt Delegierten aufrufen können Verfahren wie

picker.delegate?.pickerView?(picker, didSelectRow: 0, inComponent: 0)