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


107

私が作ってるんだUITextField持っているUIPickerViewようにinputView。コピー、貼り付け、切り取り、選択で編集できることを除けば、それで十分です。ピッカーのみがテキストフィールドを変更する必要があります。

setEnabledまたはsetUserInteractionEnabledを設定して編集を無効にできることを学びましたNO。OK、でもTextFieldはタッチに反応しなくなり、ピッカーは表示されません。

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

回答:


131

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

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

これからNOを返し、ユーザーがテキストを編集しようとしても拒否されます。

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


4
それでもタッチに反応したい場合は、「タッチアップ」ではなく「タッチダウン」で反応してください。それ以外の場合、イベントは呼び出されません。
ラドベン2012年

@NickLockwood textFieldが最初のレスポンダーになることを許可する方法はありますが、ユーザーの操作を無効にしてキャレットを非表示にする方法はありますか?
onmyway133 2014

1
@entropyユーザーがコンテンツをコピーできるようにコンテンツを選択できるようにしたいと思いますか?UITextFieldをサブクラス化すると、ほとんどすべての動作をオーバーライドできます。たとえば、ユーザーがタッチするたびにフィールドが常にすべてを選択するように強制できます。これにより、キャレットが効果的に非表示になります。
Nick Lockwood 2014

1
@LoryLory同じですが、代わりにデリゲートメソッドにSwift構文を使用します。
Nick Lockwood

5
より正確には、必要に応じて「textFieldShouldBeginEditing」を使用できます
Naveen Shan '28

22

ニックの答えを迅速に翻訳します。

P / S:falseを返す=>テキストフィールドは入力できず、キーボードで編集できません。コードでテキストを設定できるだけです。EX:textField.text = "My String Here"

override func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    return false
}

3
これは私にはうまくいきません。ズームが表示されてiOSの切り取り/コピー/貼り付けメニューが表示され、それを使用してテキストを変更できるようになるまで、テキストフィールドを長押しします。
RowanPD 2016

2
swift 4: `func textField(_ textField:UITextField、shouldChangeCharactersIn range:NSRange、replacementString string:String)-> Bool {return false}`
lionello

16

これは、最も簡単な方法です。

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

self.textfield.delegate=self;

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

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

それでおしまい!


27
これにより、ピッカーが表示されなくなり、説明されている問題が修正されません
Martin Lockett

6
@MartinLockett UIPickerViewそのデリゲートメソッドから動作をトリガーすると、うまく機能します。
Albert Bori 2015年

9

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

のカスタムサブクラスを作成するために、よりエレガントになるUITextFieldことリターンをNOへのすべての呼び出しのためにcanPerformAction:withSender:(あるいは少なくともどこactionである@selector(cut)@selector(paste)説明するように、)ここに

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


私の人生のためにそれを行う方法を考え出すことはできません。サブクラスcanPerformActionshouldChangeCharactersInRangeメソッドは呼び出されません。
Nestor

7

「非表示」にするラベルテキストなしで、UITextField全体にUIButtonを正確に配置するだけです。このボタンは、Textfieldの代わりにタッチを受信および委任でき、TextFieldのコンテンツは引き続き表示されます。


7

Swiftの場合:

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

3

MrMageが提供するソリューションを使用しました。追加する唯一のことは、UITextViewを最初のレスポンダーとして辞任する必要があることです。

これが私の迅速なコードです:

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
    }

}

1

UIPickerViewとアクションシートを処理する別の方法については、ActionSheetPickerをチェックアウトしてください

https://github.com/TimCinel/ActionSheetPicker

cocoapods対応です。アクションシートのすべてのキャンセルボタンと完了ボタンを処理します。サンプルプロジェクト内の例はすばらしいです。私は、文字列ベースのオプションだけを簡単に処理する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.
}

ポッドの更新バージョンはこちらです。 github.com/skywinder/ActionSheetPicker-3.0
Nick N

1

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

0

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

1
単純な透明なUIButton + touchUpInsideを使用しない理由に戸惑い、代わりにUIView +ジェスチャーを選択しました。
Chen Li Yong

0

inputViewが非表示のテキストフィールドで表示されるようにします。これにより、表示され無効にされたテキストのテキストも変更されます。


-5

私が使用した:

[self.textField setEnabled:NO];

そしてその仕事はうまくいきます


-7

これは私[textview setEditable:NO]; のために働きました 上記の答えは状況を複雑にしています。


1
OPは、「setEnabledまたはsetUserInteractionEnabled:NOをNOに設定することで編集を無効にできることを学びました。しかし、TextFieldがタッチに反応しなくなり、ピッカーが表示されません。」答えはすべてのイベントを停止しますが、これは望ましい結果ではありませんでした。
maninvan 2015年

@Tolgabは、このOPに関連する解決策ではありません!
Anurag Sharma
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.