UIPickerView - 1st row selection does not call didSelectRow

匿名 (未验证) 提交于 2019-12-03 01:57:01

问题:

I have a UIPickerView on my UIView along with a UITextField. I am letting the user select a value from the picker or enter a custom value in the text field.

When the user selects any option from the picker, the variable values are changed fine (in the pickerView:didSelectRow:inComponent:) method. But if the user does not select any value on the picker (coz they want to select the 1st option which is already selected), this method is not called and the selection is not reflected in the variable.

I tried setting the default value of the variable to the first option in the picker. But in that case, when the user edits the text field, the variable will have the text field's text. Now if the user decides to pick the first value again, the new value is not reflected in the variable.

How can I overcome this? Thanks.

Here's the relevant code

In my viewDidLoad I have this statement to set the selectText to first option of the picker by default

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

textFieldShouldReturn

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

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

The problem arises when the user edits the text and then decides he after all wants to use the first value of the picker. In that case they will dismiss the keyboard and click on the 1st option of the picker (which is already selected). This action does not call didSelectRow and so the value of selectText is not changed.

In order for the user to be able to change the value of selectText, they first have to select some other value from the picker and then select the 1st row.

回答1:

Instead of "pushing" the value of the picker each time you make a selection with this code:

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

you should "pull it" when the user clicks the button (or other event you are using) using something similar to:

- (void)myAction:(id)sender {      NSInteger row = [myPicker selectedRowInComponent:0];     selectedText = [myArray objectAtIndex:(NSUInteger)row];   } 

For clearing the text: The UITextField class provides a built-in button for clearing the current text. So if the user does not want that text he can discard it.

myTextField.clearButtonMode = UITextFieldViewModeAlways;  

So in the script, will you check if the TextField has a value, if it does have a value u use the TextField, if it doesn't have a value, you pull the information from the Picker.



回答2:

Can you programmatically select a row right after you instantiate the UIPickerView?

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

That last line will trigger your pickerView:didSelectRow:inComponent delegate method.

In other words, that should set the value of the variable, wherever you are storing it (NSArray? not clear).



回答3:

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


回答4:

You can directly call delegate's method like

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


回答5:

To overcome the didSelectRow not getting called in the UIPickerView when the user selected the first item in the list, you can use UITapGestureRecognizer. (Code example 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] } 

Use the following link UIGestureRecognizer Tutorial: Getting Started to get tap recognizer to work (need to add UIGestureRecognizerDelegate) and following code

class TransactionViewController: UIViewController, UITextFieldDelegate,UIPickerViewDataSource,UIPickerViewDelegate, UIGestureRecognizerDelegate  { }  func gestureRecognizer(UIGestureRecognizer,     shouldRecognizeSimultaneouslyWithGestureRecognizer:UIGestureRecognizer) -> Bool {         return true } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!