UIPickerView
にUIView
と一緒にUITextField
があります。ユーザーがピッカーから値を選択するか、テキストフィールドにカスタム値を入力できるようにしています。
ユーザーがピッカーからオプションを選択すると、変数値が正しく変更されます(pickerView:didSelectRow:inComponent:
) 方法。ただし、ユーザーがピッカーで値を選択しない場合(既に選択されている最初のオプションを選択したい場合)、このメソッドは呼び出されず、選択は変数に反映されません。
変数のデフォルト値をピッカーの最初のオプションに設定してみました。ただし、その場合、ユーザーがテキストフィールドを編集すると、変数にはテキストフィールドのテキストが含まれます。これで、ユーザーが最初の値を再度選択することにした場合、新しい値は変数に反映されません。
どうすればこれを克服できますか?ありがとう。
関連するコードは次のとおりです
私のviewDidLoad
には、デフォルトでselectText
をピッカーの最初のオプションに設定するこのステートメントがあります
[self setSelectText:[myArray objectAtIndex:0]];
textFieldShouldReturn
- (BOOL)textFieldShouldReturn:(UITextField *)txtField{
[txtField resignFirstResponder];
[self setSelectText:txtField.text];
return YES;
}
PickerViewDelegateの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]]];
}
この問題は、ユーザーがテキストを編集してから、結局、ピッカーの最初の値を使用することを決定したときに発生します。その場合、彼らはキーボードを閉じて、ピッカーの最初のオプション(すでに選択されている)をクリックします。このアクションはdidSelectRow
を呼び出さないため、selectTextの値は変更されません。
ユーザーがselectText
の値を変更できるようにするには、最初にピッカーから他の値を選択してから、最初の行を選択する必要があります。
このコードで選択を行うたびにピッカーの値を「プッシュ」する代わりに、次のようにします。
- (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
。
次のようなデリゲートのメソッドを直接呼び出すことができます
picker.delegate?.pickerView?(picker, didSelectRow: 0, inComponent: 0)
-(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
}
UIPickerViewをインスタンス化した直後に、プログラムで行を選択できますか?
int firstRow = 0;
int firstOptionIndex = 0;
[myPickerView selectRow:firstRow inComponent:firstOptionIndex animated:NO];
その最後の行は、pickerView:didSelectRow:inComponent
デリゲートメソッドをトリガーします。
つまり、変数を格納する場所に関係なく、変数の値を設定する必要があります(NSArray
?は明確ではありません)。
ユーザーがリストの最初の項目を選択したときにUIPickerViewで呼び出されないdidSelectRowを克服するには、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]
}
次のリンクを使用してください IGestureRecognizerチュートリアル:はじめに タップレコグナイザーを機能させるには(UIGestureRecognizerDelegateを追加する必要があります)、次のコードを使用します
class TransactionViewController: UIViewController, UITextFieldDelegate,UIPickerViewDataSource,UIPickerViewDelegate, UIGestureRecognizerDelegate { }
func gestureRecognizer(UIGestureRecognizer,
shouldRecognizeSimultaneouslyWithGestureRecognizer:UIGestureRecognizer) -> Bool {
return true
}