UIPickerView - выбор 1-й строки не вызывает didSelectRow - PullRequest
19 голосов
/ 25 апреля 2009

У меня есть UIPickerView на моем UIView вместе с UITextField. Я позволяю пользователю выбрать значение из средства выбора или ввести пользовательское значение в текстовое поле.

Когда пользователь выбирает какую-либо опцию в средстве выбора, значения переменных меняются (в методе pickerView:didSelectRow:inComponent:). Но если пользователь не выбирает какое-либо значение в средстве выбора (поскольку он хочет выбрать 1-й вариант, который уже выбран), этот метод не вызывается, и выбор не отражается в переменной.

Я попытался установить значение переменной по умолчанию для первого параметра в средстве выбора. Но в этом случае, когда пользователь редактирует текстовое поле, переменная будет иметь текстовое поле текста. Теперь, если пользователь решит снова выбрать первое значение, новое значение не будет отражено в переменной.

Как я могу преодолеть это? Спасибо.

Вот соответствующий код

В моем viewDidLoad у меня есть это утверждение, чтобы установить selectText на первый вариант выбора по умолчанию

[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]]];
}

Проблема возникает, когда пользователь редактирует текст, а затем решает, что он все-таки хочет использовать первое значение средства выбора. В этом случае они отклонят клавиатуру и нажмут на 1-й вариант выбора (который уже выбран). Это действие не вызывает didSelectRow, поэтому значение selectText не изменяется.

Чтобы пользователь мог изменить значение selectText, ему сначала нужно выбрать другое значение из средства выбора, а затем выбрать 1-ую строку.

Ответы [ 5 ]

26 голосов
/ 26 апреля 2009

Вместо «нажатия» значения выбора каждый раз, когда вы делаете выбор с помощью этого кода:

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

Вы должны «потянуть», когда пользователь нажимает кнопку (или другое событие, которое вы используете), используя что-то похожее на:

- (void)myAction:(id)sender
{

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


}

Для очистки текста: класс UITextField предоставляет встроенную кнопку для очистки текущего текста. Поэтому, если пользователь не хочет этот текст, он может от него отказаться.

myTextField.clearButtonMode = UITextFieldViewModeAlways; 

Таким образом, в сценарии вы проверите, имеет ли TextField значение, если оно имеет значение, и вы используете TextField, если оно не имеет значения, вы извлекаете информацию из Picker.

5 голосов
/ 15 марта 2017

Вы можете напрямую вызвать метод делегата, как

picker.delegate?.pickerView?(picker, didSelectRow: 0, inComponent: 0)
3 голосов
/ 03 февраля 2015
-(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
}
2 голосов
/ 25 апреля 2009

Можете ли вы программно выбрать строку сразу после создания UIPickerView?

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

Эта последняя строка вызовет ваш pickerView:didSelectRow:inComponent метод делегата.

Другими словами, это должно установить значение переменной, где бы вы ни хранили ее (NSArray? Не ясно).

0 голосов
/ 18 июня 2015

Чтобы преодолеть, что didSelectRow не вызывается в UIPickerView, когда пользователь выбрал первый элемент в списке, вы можете использовать UITapGestureRecognizer. (Пример кода в 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]
}

Используйте следующую ссылку Учебное пособие по UIGestureRecognizer: Начало работы , чтобы заставить работать распознаватель касаний (необходимо добавить UIGestureRecognizerDelegate) и следующий код

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

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