it-swarm.com.ru

Как отключить редактирование UITextField, но все еще принимать касание?

Я создаю UITextField, который имеет UIPickerView как inputView. Все хорошо, за исключением того, что я могу редактировать, копировать, вставлять, вырезать и выделять текст, а я этого не хочу. Только сборщик должен изменять текстовое поле.

Я узнал, что я могу отключить редактирование, установив setEnabled или setUserInteractionEnabled в NO. Хорошо, но TextField перестает реагировать на прикосновения, и средство выбора не отображается.

Что я могу сделать, чтобы достичь этого?

98
Luiz de Prá

Используя делегат текстового поля, есть метод

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

Верните NO из этого, и любая попытка пользователя отредактировать текст будет отклонена.

Таким образом, вы можете оставить поле включенным, но при этом запретить людям вставлять в него текст.

122
Nick Lockwood

Это было бы самым простым из всех:

в viewDidLoad: (установите делегат только для текстовых полей, которые не должны редактироваться.

self.textfield.delegate=self;

и вставьте эту делегатскую функцию:

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

Это оно!

16
Ankish Jain

Переведите ответ Ник в 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
}
16
lee

В 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

Было бы более элегантно создать собственный подкласс UITextField, который возвращает NO для всех вызовов canPerformAction:withSender: (или, по крайней мере, где action равен @selector(cut) или @selector(paste)), как описано здесь .

Кроме того, я бы также реализовал - (BOOL) textField: (UITextField *) textField shouldChangeCharactersInRange: (NSRange) range replaceString: (NSString *) строку в соответствии с предложением Ника, чтобы отключить ввод текста с клавиатур Bluetooth.

7
MrMage

в Swift:

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

Просто поместите UIButton точно по всему UITextField без текста Label, что делает его "невидимым". Эта кнопка может получать и делегировать касания вместо текстового поля, а содержимое текстового поля все еще отображается.

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 и Action Sheets, извлеките 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

Чтобы предотвратить редактирование UITextField при использовании UIPickerView для выбора значений (в 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