UITextField
としてUIPickerView
を持つinputView
を作成しています。コピー、貼り付け、切り取り、テキストの選択による編集が可能であり、それを望まないことを除いて、そのすべては良好です。テキストフィールドを変更するのはピッカーだけです。
setEnabled
またはsetUserInteractionEnabled
をNO
に設定することにより、編集を無効にできることを学びました。わかりましたが、TextFieldはタッチに対する応答を停止し、ピッカーは表示されません。
それを達成するために何ができますか?
テキストフィールドのデリゲートを使用して、メソッドがあります
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
これからNOを返すと、ユーザーによるテキストの編集は拒否されます。
そうすれば、フィールドを有効にしたまま、テキストを貼り付けることを防ぐことができます。
Nickの答えをSwiftに翻訳します。
P/S:falseを返す=>テキストフィールドはキーボードで入力、編集できません。コードでテキストを設定できます。EX:textField.text = "My String Here"
override func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
return false
}
これはすべての中で最も簡単です:
viewDidLoad :(デリゲートは編集不可のテキストフィールドにのみ設定します。
self.textfield.delegate=self;
そして、このデリゲート関数を挿入します:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
return NO;
}
それでおしまい!
Swift 3+の場合:
class MyViewController: UIViewController, UITextFieldDelegate {
override func viewDidLoad() {
self.myTextField.delegate = self
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
if textField == myTextField {
// code which you want to execute when the user touch myTextField
}
return false
}
}
here のように、canPerformAction:withSender:
(または少なくともUITextField
が@selector(cut)
または@selector(paste)
である場合)へのすべての呼び出しに対してNO
を返すaction
のカスタムサブクラスを作成すると、よりエレガントになります。
さらに、Bluetoothキーボードからのテキスト入力を無効にするために、ニックの提案に従って-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)stringも実装します。
In Swift:
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
questionField.resignFirstResponder();
// Additional code here
return false
}
UITextField全体に正確にUIButtonを配置し、Label-textを使用せずに「非表示」にします。このボタンは、Textfieldの代わりにタッチを受信および委任でき、TextFieldのコンテンツは引き続き表示されます。
MrMageが提供するソリューションを使用しました。追加する唯一のことは、UITextViewをファーストレスポンダーとして辞任することです。そうしないと、選択したテキストで止まってしまいます。
これが私のSwiftコードです:
class TouchableTextView : UITextView {
override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
self.resignFirstResponder()
return false
}
override func shouldChangeTextInRange(range: UITextRange, replacementText text: String) -> Bool {
self.resignFirstResponder()
return false
}
}
UIPickerViewとアクションシートを処理する代替手段については、ActionSheetPickerをチェックアウトしてください。
https://github.com/TimCinel/ActionSheetPicker
ココアポッドが有効になっています。アクションシートのすべてのキャンセルボタンと完了ボタンを処理します。サンプルプロジェクト内の例は素晴らしいです。文字列ベースのオプションだけを簡単に処理するActionSheetStringPickerを選択しますが、APIは考えられるほとんどすべてを処理できます。
私はもともとチェックマークの付いた答えによく似たソリューションを開始しましたが、このプロジェクトにつまずいて、ココポッドの使用を含む使用のためにアプリに統合するのに約20分かかりました:ActionSheetPicker(〜> 0.0)
お役に立てれば。
Gitプロジェクトをダウンロードして、次のクラスを見てください。
ここに追加したコードの大部分と、*。hのインポートがほぼあります。
- (IBAction)gymTouched:(id)sender {
NSLog(@"gym touched");
[ActionSheetStringPicker showPickerWithTitle:@"Select a Gym" rows:self.locations initialSelection:self.selectedIndex target:self successAction:@selector(gymWasSelected:element:) cancelAction:@selector(actionPickerCancelled:) Origin:sender];
}
- (void)actionPickerCancelled:(id)sender {
NSLog(@"Delegate has been informed that ActionSheetPicker was cancelled");
}
- (void)gymWasSelected:(NSNumber *)selectedIndex element:(id)element {
self.selectedIndex = [selectedIndex intValue];
//may have originated from textField or barButtonItem, use an IBOutlet instead of element
self.txtGym.text = [self.locations objectAtIndex:self.selectedIndex];
}
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
return NO; // Hide both keyboard and blinking cursor.
}
値を選択するためにUIPickerViewを使用しているときにUITextFieldが編集されないようにするには(Swiftで):
self.txtTransDate = self.makeTextField(self.transDate, placeHolder: "Specify Date")
self.txtTransDate?.addTarget(self, action: "txtTransDateEditing:", 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 txtTransDateEditing(sender: UITextField) {
var datePickerView:UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerView
datePickerView.addTarget(self, action: Selector("datePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)
}
func datePickerValueChanged(sender: UIDatePicker) {
var dateformatter = NSDateFormatter()
dateformatter.dateStyle = NSDateFormatterStyle.MediumStyle
self.txtTransDate!.text = dateformatter.stringFromDate(sender.date)
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
self.resignFirstResponder()
return false
}
InputViewを非表示のテキストフィールドで表示します。これにより、表示および無効化されたテキストフィールドのテキストも変更されます。
この回避策は機能します。テキストフィールドの上に透明なUIViewを配置し、次のコードを実装します。
- (void)viewDidLoad
{
[super viewDidLoad];
UILongPressGestureRecognizer *press = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress)];
[transparentView addGestureRecognizer:press];
[press release];
press = nil;
}
-(void)longPress
{
txtField.userInteractionEnabled = NO;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
txtField.userInteractionEnabled = YES;
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[txtField becomeFirstResponder];
}