ios 如何禁用 UITextField 编辑但仍接受触摸?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9116969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:39:23  来源:igfitidea点击:

How to disable UITextField editing but still accept touch?

iosuitextfielduipickerview

提问by Luiz de Prá

I'm making a UITextFieldthat has a UIPickerViewas inputView. Its all good, except that I can edit by copy, paste, cut and select text, and I don't want it. Only the Picker should modify text field.

我正在制作UITextField一个UIPickerViewas inputView。一切都很好,只是我可以通过复制,粘贴,剪切和选择文本进行编辑,而我不想要它。只有选择器应该修改文本字段。

I've learned that I can disable editing by setting setEnabledor setUserInteractionEnabledto NO. Ok, but the TextField stop responding to touching and the picker don't show up.

我了解到我可以通过设置setEnabledsetUserInteractionEnabled来禁用编辑NO。好的,但是 TextField 停止响应触摸并且选择器不显示。

What can I do to achieve it?

我能做些什么来实现它?

回答by Nick Lockwood

Using the textfield delegate, there's a method

使用文本字段委托,有一个方法

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

Return NO from this, and any attempt by the user to edit the text will be rejected.

从此返回 NO,用户编辑文本的任何尝试都将被拒绝。

That way you can leave the field enabled but still prevent people pasting text into it.

这样,您可以启用该字段,但仍会阻止人们将文本粘贴到其中。

回答by lee

Translate the answer of Nickto swift:

Nick的回答翻译成 swift:

P/S: Return false => the textfields cannot input, edit by the keyboard. It just can set text by code.EX: textField.text = "My String Here"

P/S: Return false => 文本框无法输入,键盘编辑。它只能通过代码设置文本。EX: textField.text = "My String Here"

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

回答by Ankish Jain

This would be the simplest of all:

这将是最简单的:

in viewDidLoad:(set the delegate only for textfields which should not be editable.

在 viewDidLoad:( 仅为不应可编辑的文本字段设置委托。

self.textfield.delegate=self;

and insert this delegate function:

并插入这个委托函数:

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

Thats it!

就是这样!

回答by Nadeesha Lakmal

In swift 3+ :

在 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
   }
}

回答by Saranya

In Swift:

在斯威夫特:

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

回答by Timm Kent

Simply place a UIButton exactly over the entire UITextField with no Label-text which makes it "invisible". This button can receive and delegate touches instead of the Textfield and the content of the TextField is still visible.

只需将一个 UIButton 准确地放在整个 UITextField 上,没有标签文本,这使它“不可见”。此按钮可以接收和委托触摸而不是 Textfield,并且 TextField 的内容仍然可见。

回答by MrMage

It would be more elegant to create a custom subclass of UITextFieldthat returns NOfor all calls to canPerformAction:withSender:(or at least where actionis @selector(cut)or @selector(paste)), as described here.

这将是更优雅创建的自定义子类UITextField是回报NO所有调用canPerformAction:withSender:(或至少是action@selector(cut)@selector(paste)),如所描述这里

In addition, I'd also implement - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string as per Nick's suggestion in order to disable inputting text from Bluetooth keyboards.

此外,我还将按照尼克的建议实施 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 以禁用从蓝牙键盘输入文本。

回答by Leedrick

I used the solution provided by MrMage. The only thing I'd add is you should resign the UITextView as first responder, otherwise you're stuck with the text selected.

我使用了 MrMage 提供的解决方案。我唯一要补充的是,您应该将 UITextView 辞职为第一响应者,否则您会被选中的文本卡住。

Here's my swift code:

这是我的快速代码:

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
    }

}

回答by Thiru

To prevent editing of UITextField while using UIPickerView for selecting values(in Swift):

防止在使用 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
}

回答by Nick N

For an alternative that handles the UIPickerView and Action Sheets, checkout ActionSheetPicker

对于处理 UIPickerView 和 Action Sheets 的替代方法,请查看 ActionSheetPicker

https://github.com/TimCinel/ActionSheetPicker

https://github.com/TimCinel/ActionSheetPicker

It's cocoapods enabled. It handles all of the cancel and done buttons on the Action Sheet. The examples within the sample project are great. I choose the ActionSheetStringPicker, which handles easily just String based options, but the API can handle most anything that I can think of.

它启用了 cocoapods。它处理操作表上的所有取消和完成按钮。示例项目中的示例很棒。我选择 ActionSheetStringPicker,它可以轻松处理基于字符串的选项,但 API 可以处理我能想到的大多数事情。

I originally started a solution much like the checkmarked answer, but stumbled onto this project and took me roughly 20 minutes to get things integrated into my app for usage including using cocopods: ActionSheetPicker (~> 0.0)

我最初开始了一个很像复选标记的答案的解决方案,但偶然发现了这个项目,我花了大约 20 分钟将东西集成到我的应用程序中以供使用,包括使用 cocopods:ActionSheetPicker (~> 0.0)

Hope this helps.

希望这可以帮助。

Download the git project and look at the following classes:

下载git项目,查看如下类:

  • ActionSheetPickerViewController.m
  • ActionSheetPickerCustomPickerDelegate.h
  • ActionSheetPickerViewController.m
  • ActionSheetPickerCustomPickerDelegate.h

Here is roughly most of the code that I added, plus the *.h imports.

这里大致是我添加的大部分代码,加上 *.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.
}