web-dev-qa-db-ja.com

UITextFieldの編集を無効にしながらタッチを受け入れる方法は?

UITextFieldとしてUIPickerViewを持つinputViewを作成しています。コピー、貼り付け、切り取り、テキストの選択による編集が可能であり、それを望まないことを除いて、そのすべては良好です。テキストフィールドを変更するのはピッカーだけです。

setEnabledまたはsetUserInteractionEnabledNOに設定することにより、編集を無効にできることを学びました。わかりましたが、TextFieldはタッチに対する応答を停止し、ピッカーは表示されません。

それを達成するために何ができますか?

101
Luiz de Prá

テキストフィールドのデリゲートを使用して、メソッドがあります

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

これからNOを返すと、ユーザーによるテキストの編集は拒否されます。

そうすれば、フィールドを有効にしたまま、テキストを貼り付けることを防ぐことができます。

124
Nick Lockwood

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
}
17
lee

これはすべての中で最も簡単です:

viewDidLoad :(デリゲートは編集不可のテキストフィールドにのみ設定します。

self.textfield.delegate=self;

そして、このデリゲート関数を挿入します:

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
return NO;
}

それでおしまい!

16
Ankish Jain

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
   }
}
7
Nadeesha Lakmal

here のように、canPerformAction:withSender:(または少なくともUITextField@selector(cut)または@selector(paste)である場合)へのすべての呼び出しに対してNOを返すactionのカスタムサブクラスを作成すると、よりエレガントになります。

さらに、Bluetoothキーボードからのテキスト入力を無効にするために、ニックの提案に従って-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)stringも実装します。

7
MrMage

In Swift:

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
    questionField.resignFirstResponder();
    // Additional code here
    return false
}
7
Saranya

UITextField全体に正確にUIButtonを配置し、Label-textを使用せずに「非表示」にします。このボタンは、Textfieldの代わりにタッチを受信および委任でき、TextFieldのコンテンツは引き続き表示されます。

6
Timm Kent

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
    }

}
3
Leedrick

UIPickerViewとアクションシートを処理する代替手段については、ActionSheetPickerをチェックアウトしてください。

https://github.com/TimCinel/ActionSheetPicker

ココアポッドが有効になっています。アクションシートのすべてのキャンセルボタンと完了ボタンを処理します。サンプルプロジェクト内の例は素晴らしいです。文字列ベースのオプションだけを簡単に処理するActionSheetStringPickerを選択しますが、APIは考えられるほとんどすべてを処理できます。

私はもともとチェックマークの付いた答えによく似たソリューションを開始しましたが、このプロジェクトにつまずいて、ココポッドの使用を含む使用のためにアプリに統合するのに約20分かかりました:ActionSheetPicker(〜> 0.0)

お役に立てれば。

Gitプロジェクトをダウンロードして、次のクラスを見てください。

  • ActionSheetPickerViewController.m
  • ActionSheetPickerCustomPickerDelegate.h

ここに追加したコードの大部分と、*。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.
}
1
Nick N

値を選択するために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
}
1
Thiru

InputViewを非表示のテキストフィールドで表示します。これにより、表示および無効化されたテキストフィールドのテキストも変更されます。

0
Sandro Vezzali

この回避策は機能します。テキストフィールドの上に透明な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];
}
0
cocoakomali