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

时间:2012-02-02 17:29:45

标签: ios uitextfield uipickerview

我正在制作UITextField UIPickerViewinputView。它很好,除了我可以通过复制,粘贴,剪切和选择文本进行编辑,我不想要它。只有Picker才能修改文本字段。

我了解到我可以通过将setEnabledsetUserInteractionEnabled设置为NO来禁用编辑功能。好的,但是TextField停止响应触摸并且选择器没有出现。

我能做些什么来实现它?

15 个答案:

答案 0 :(得分:122)

使用textfield委托,有一个方法

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

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

通过这种方式,您可以启用该字段,但仍然可以阻止人们将文本粘贴到其中。

答案 1 :(得分:16)

这将是最简单的:

viewDidLoad中的

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

self.textfield.delegate=self;

并插入此委托函数:

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

多数民众赞成!

答案 2 :(得分:15)

Nick 的答案翻译成swift:

P / S:返回false =>文本字段无法输入,键盘编辑。它只能通过code.EX:textField.text =“My String Here”

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

答案 3 :(得分:7)

创建UITextField的自定义子类会更加优雅,对NO的所有调用都返回canPerformAction:withSender:(或至少action@selector(cut)@selector(paste)),如here所述。

另外,我也会实施      - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 根据尼克的建议,为了禁止从蓝牙键盘输入文字。

答案 4 :(得分:7)

在Swift中:

private void savePreferencesForImages(ArrayList<Image> imageList)
{
    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    Gson gson = new Gson();
    int imgKey = 0;
    for (Image img: imageList) {
        String json = gson.toJson(imageList);
        editor.putString("" + imgKey,json);
        editor.commit();
        imgKey++;
    }
}


private ArrayList<Image> loadPreferences()
{
    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
    Gson gson = new Gson();
    Map<String, ?> allPrefs = sharedPreferences.getAll();
    String gsonString = sharedPreferences.getString("userImages", "");
    ArrayList<Image> images = new ArrayList<Image>();
    if (!allPrefs.isEmpty()) {
        for (Map.Entry<String, ?> entry : allPrefs.entrySet()) {
            String json = entry.getValue().toString();
            Image temp = gson.fromJson(json, Image.class);
            images.add(temp);
        }
    }
    return images;
}

答案 5 :(得分:7)

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

答案 6 :(得分:6)

只需将UIButton准确地放在整个UITextField上,不使用Label-text,这样就可以看到&#34;隐藏&#34;。此按钮可以接收和委托触摸而不是文本字段,并且TextField的内容仍然可见。

答案 7 :(得分:1)

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

https://github.com/TimCinel/ActionSheetPicker

启用了cocoapods。它处理操作表上的所有取消和完成按钮。示例项目中的示例非常棒。我选择了ActionSheetStringPicker,它可以轻松处理基于String的选项,但API可以处理我能想到的大部分内容。

我最初开始的解决方案很像勾选的答案,但偶然发现了这个项目并花了大约20分钟将我的应用集成到我的应用程序中,包括使用cocopods:ActionSheetPicker(〜&gt; 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.
}

答案 8 :(得分: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
}

答案 9 :(得分: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];
}

答案 10 :(得分:0)

使您的inputView由隐藏的文本字段显示,该文本字段也会更改显示和禁用的文本。

答案 11 :(得分:0)

不能完全确定这是多么的棘手,但对我而言,唯一能解决问题的方法是添加目标操作并调用endEditing。由于选择器控制我的UITextField.text值,因此我可以在用户单击该字段后立即关闭键盘。这是一些代码:

uiTextFieldVariable.addTarget(self, action: #selector(dismissKeyboard), for: .editingDidBegin)

@objc private func dismissKeyboard() {
    endEditing(true)
}

答案 12 :(得分:0)

如果您准备好创建自定义文本字段,那么您可以使用另一个 stackoverflow 问题中的答案。 https://stackoverflow.com/a/42698689/9369035

只需覆盖上面答案中的这三个方法就足够了。至少就我测试而言。

答案 13 :(得分:-4)

我用过:

[self.textField setEnabled:NO];

并且工作正常

答案 14 :(得分:-7)

这对我有用 [textview setEditable:NO]; 上述答案使情况过于复杂。