2009-04-25 16 views
18

Tengo UIPickerView en mi UIView junto con UITextField. Dejo que el usuario seleccione un valor del selector o ingrese un valor personalizado en el campo de texto.UIPickerView - la selección de la 1ra fila no llama a didSelectRow

Cuando el usuario selecciona cualquier opción del selector, los valores de las variables cambian bien (en el método pickerView:didSelectRow:inComponent:). Pero si el usuario no selecciona ningún valor en el selector (porque quieren seleccionar la primera opción que ya está seleccionada), este método no se llama y la selección no se refleja en la variable.

He intentado establecer el valor por defecto de la variable a la primera opción en el selector. Pero en ese caso, cuando el usuario edite el campo de texto, la variable tendrá el texto del campo de texto. Ahora, si el usuario decide elegir el primer valor nuevamente, el nuevo valor no se refleja en la variable.

¿Cómo puedo superar esto? Gracias.

Aquí está el código correspondiente

En mi viewDidLoad tengo esta declaración para establecer el selectText a la primera opción del selector de forma predeterminada

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

textFieldShouldReturn

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

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

El problema surge cuando el usuario edita el texto y luego decide que después de todo, quiere utilizar el primer valor del selector. En ese caso, cerrarán el teclado y harán clic en la primera opción del selector (que ya está seleccionado). Esta acción no llama al didSelectRow, por lo que el valor de selectText no cambia.

Para que el usuario pueda cambiar el valor de selectText, primero tiene que seleccionar algún otro valor del selector y luego seleccionar la 1ª fila.

+0

Si puede, publique parte de su código en relación con este problema. Esto ayudará con la resolución de problemas. –

Respuesta

25

En lugar de "empujar" el valor del selector cada vez que realice una selección con este código:

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

debe "tirar" cuando el usuario hace clic en el botón (u otro evento que está utilizando) usando algo similar a:

- (void)myAction:(id)sender 
{ 

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


} 

para despejar el texto: la clase UITextField proporciona un botón incorporado para despejar el texto actual. Entonces, si el usuario no quiere ese texto, puede descartarlo.

myTextField.clearButtonMode = UITextFieldViewModeAlways; 

Así que en el guión, le comprobar si el TextField tiene un valor, si tiene un valor u utilizar el campo de texto, si no tiene un valor, que tire de la información de la Picker.

+0

Gracias. Pero el problema aquí es que el usuario tiene la opción de especificar un valor personalizado en un campo de texto. Entonces, existe la posibilidad de que el usuario ingrese texto. Ahora, si hago lo que sugirió, no se tendrá en cuenta el valor que ingrese el usuario. – lostInTransit

+1

La clase UITextField también proporciona un botón incorporado para borrar el texto actual. Entonces, si el usuario no quiere ese texto, puede descartarlo. myTextField.clearButtonMode = UITextFieldViewModeAlways; –

+0

He actualizado la respuesta. –

2

¿Puede programación seleccionar una fila justo después de crear una instancia de la UIPickerView?

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

Esa última línea dará lugar a su método de pickerView:didSelectRow:inComponent delegado.

En otras palabras, que debe establecer el valor de la variable, esté donde esté almacenando (NSArray? No está claro).

+0

Eso sería suficiente. Pero supongamos que el usuario decide ingresar un valor personalizado en el campo de texto. Y luego decide que, después de todo, quiere usar el primer valor en el selector. Entonces, selectText tiene el valor que se ingresó en el campo de texto. Y el usuario simplemente hace clic en la 1ra fila pensando que anulará el valor ingresado en el campo de texto. Pero eso no sucedería porque el programa no sabría que el usuario hizo tapping en la primera opción. – lostInTransit

+0

El hecho de tocar la primera fila de una vista de selector no genera el evento de selección, ya que puede ser simplemente una "deficiencia" con el diseño de UIPickerView cuando lo necesite, pero no es necesariamente un problema con UITextField. Considere la posibilidad de presentar una mejora de características en UIPickerView en http://bugreporter.apple.com. –

+0

Estoy viendo un comportamiento diferente. Mi método delegado no se activa cuando muevo el selector programáticamente como usted describe. Dispara como se espera si realmente muevo el selector usando la IU. Tiene sentido para mí que el delegado no dispare. Como muevo el selector programáticamente, sé que se movió, así que puedo manejar las actualizaciones necesarias en ese momento. – 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

la llamada forzada al delegado hizo el trabajo –

0

para superar la didSelectRow no conseguir llamada en el UIPickerView cuando el usuario selecciona el primer elemento de la lista, puede utilizar UITapGestureRecognizer. (Ejemplo de código en 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] 
} 

Usa el siguiente enlace UIGestureRecognizer Tutorial: Getting Started para obtener reconocedor del grifo para trabajar (necesidad de añadir UIGestureRecognizerDelegate) y el siguiente código

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

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

Puede llamar directamente el método de delegado como

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