Подтвердить что ты не робот

Как отключить вставку в TextField в Swift?

У меня есть TextField с числовой панелью, и функция запускается только в том случае, если она содержит числа.

Единственная опция, с которой пользователь будет разбивать приложение, - это вставить буквы в TextField и нажать "ОК".

Как отключить вставку в TextField?

4b9b3361

Ответ 1

Я согласен с Леонардо Савио Дабусом, если бы я был вами, я буду использовать проверку строк и просто выдаст предупреждение, это упростит ситуацию. НО, если отключить параметр вставки - это фантастическая функция, которую вы действительно хотите добавить в свое приложение, тогда вам нужно сделать больше работы. Я предоставлю следующие шаги.

Шаг 1: вам нужно создать другой класс, который расширяет UITextField. В этом примере я сделал CustomUITextField.

import Foundation
import UIKit  // don't forget this

class CustomUITextField: UITextField {
    override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
        if action == "paste:" {
            return false
        }        
        return super.canPerformAction(action, withSender: sender)
    }
}

Шаг 2: Проведите раскадровку с помощью ViewController. Вам нужно объявить IBOutlet, как в обычном случае:

@IBOutlet var textFieldA: CustomUITextField?

Проведите круг рядом с @IBOutlet на textField в раскадровке. THEN, это важно и легко игнорировать:

  • Перейдите к раскадровке.
  • Щелкните целевой TextField
  • Выберите Identity Inspector (третий)
  • Измените класс как CustomUITextField

Быстрый снимок приведен ниже.

enter image description here

Чтобы это, надеюсь, это сработает.

Кредит:

В основном ссылка из https://teamtreehouse.com/forum/disable-paste-in-uitextfielduitextview-swift

Если вы хотите узнать больше о поведении метода canPerformAction, но это версия objective-C, но общие понятия: Как я могу обнаружить, что пользователь нажал кнопка форматирования в UIMenuController?

Ответ 2

Для Swift 3 он изменился на:

override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    if action == #selector(copy(_:)) || action == #selector(paste(_:)) {
        return false
    }

    return true
}

Ответ 3

Для Swift3

UIResponder​Standard​Edit​Actions были недавно добавлены (iOS 10. 0+), с помощью которых мы можем безопасно проверить, является ли действие "вставкой" или нет.

import UIKit

class NMTextField: UITextField {
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if action == #selector(UIResponderStandardEditActions.paste(_:)) {
            return false
        }
        return super.canPerformAction(action, withSender: sender)
    }
}

Ответ 4

подробности

  • Xcode 9.1, Swift 4
  • Xcode 10.2 (10E125), Swift 5

Решение 1

// class TextField: UITextField
extension UITextField {

    open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        return action == #selector(UIResponderStandardEditActions.cut) || action == #selector(UIResponderStandardEditActions.copy)
    }
}

Использование решения 1

let textField = UITextField(frame: CGRect(x: 50, y: 120, width: 200, height: 50))
textField.borderStyle = .roundedRect
view.addSubview(textField)

Решение 2

enum ResponderStandardEditActions {
    case cut, copy, paste, select, selectAll, delete
    case makeTextWritingDirectionLeftToRight, makeTextWritingDirectionRightToLeft
    case toggleBoldface, toggleItalics, toggleUnderline
    case increaseSize, decreaseSize

    var selector: Selector {
        switch self {
        case .cut:
            return #selector(UIResponderStandardEditActions.cut)
        case .copy:
            return #selector(UIResponderStandardEditActions.copy)
        case .paste:
            return #selector(UIResponderStandardEditActions.paste)
        case .select:
            return #selector(UIResponderStandardEditActions.select)
        case .selectAll:
            return #selector(UIResponderStandardEditActions.selectAll)
        case .delete:
            return #selector(UIResponderStandardEditActions.delete)
        case .makeTextWritingDirectionLeftToRight:
            return #selector(UIResponderStandardEditActions.makeTextWritingDirectionLeftToRight)
        case .makeTextWritingDirectionRightToLeft:
            return #selector(UIResponderStandardEditActions.makeTextWritingDirectionRightToLeft)
        case .toggleBoldface:
            return #selector(UIResponderStandardEditActions.toggleBoldface)
        case .toggleItalics:
            return #selector(UIResponderStandardEditActions.toggleItalics)
        case .toggleUnderline:
            return #selector(UIResponderStandardEditActions.toggleUnderline)
        case .increaseSize:
            return #selector(UIResponderStandardEditActions.increaseSize)
        case .decreaseSize:
            return #selector(UIResponderStandardEditActions.decreaseSize)
        }
    }

}

class TextField: UITextField {

    var allowedActions: [ResponderStandardEditActions] = [] {
        didSet {
            if !allowedActions.isEmpty && !notAllowedActions.isEmpty {
                notAllowedActions = []
            }
        }
    }

    var notAllowedActions: [ResponderStandardEditActions] = [] {
          didSet {
            if !allowedActions.isEmpty && !notAllowedActions.isEmpty {
                allowedActions = []
            }
        }
    }

    open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {

        if !allowedActions.isEmpty {
            return allowedActions.map{ $0.selector }.contains(action)
        }

        if !notAllowedActions.isEmpty {
            return !notAllowedActions.map{ $0.selector }.contains(action)
        }
        return super.canPerformAction(action, withSender: sender)
    }
}

Использование решения 2

let textField = TextField(frame: CGRect(x: 50, y: 50, width: 200, height: 50))
textField.borderStyle = .roundedRect
view.addSubview(textField)
textField.allowedActions = [.copy, .cut]
//textField.notAllowedActions = [.copy, .cut]

Ответ 5

Вы можете создать расширение для UITextField и переопределить canPerformAction:

override public func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
        return (action != "paste:") 
}

Ответ 6

В реальной быстрой версии (2.2, начиная с 3.0) этот код функции должен быть реорганизован на:

override public func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
    if action == #selector(NSObject.copy(_:)) || action == #selector(NSObject.paste(_:)) {
        return false
    }

    return true
}

Ответ 7

Swift 4.1, этот код отлично работает с ViewController.

1) Отключить все опции (копировать, вставлять, удалять..... и т.д.)

extension UITextField {

    open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        return false
    }
}

2) Включить конкретную опцию (выбрать, выбрать все... и т.д.)

extension UITextField {

open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    return action == #selector(UIResponderStandardEditActions.select(_:)) || action == #selector(UIResponderStandardEditActions.selectAll(_:))
}

Ответ 8

Вы можете просто привязать IBAction к вашим отправленным событиям (редактирование изменено) вашего текстового поля, чтобы отфильтровать не номера из вашей строки при вводе следующим образом:

@IBAction func changedTextAction(sender: UITextField) {
    sender.text = String(Array(sender.text).map{String($0)}.filter{ $0.toInt() != nil }.map{Character($0)} )
}

Ответ 9

class CustomUITextField: UITextField {
    override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if action == #selector(cut(_:)) ||
           action == #selector(copy(_:)) ||  
           action == #selector(UIResponderStandardEditActions.paste(_:)) || 
           action == #selector(UIResponderStandardEditActions.select(_:)) || 
           action == #selector(UIResponderStandardEditActions.selectAll(_:)) || 
           action == #selector(UIResponderStandardEditActions.delete(_:)) ||  
           action == #selector(UIResponderStandardEditActions.makeTextWritingDirectionLeftToRight(_:)) ||  
           action == #selector(UIResponderStandardEditActions.makeTextWritingDirectionRightToLeft(_:)) || 
           action == #selector(UIResponderStandardEditActions.toggleBoldface(_:)) || 
           action == #selector(UIResponderStandardEditActions.toggleItalics(_:)) || 
           action == #selector(UIResponderStandardEditActions.toggleUnderline(_:)) || 
           action == #selector(UIResponderStandardEditActions.increaseSize(_:)) || 
           action == #selector(UIResponderStandardEditActions.decreaseSize(_:)) 
        {
             return false
        };
        return true
    }
}

Ответ 10

Я создал собственный класс для textField. Я обработал случай, когда вы хотите включить/отключить действия над текстовым полем. Вы можете настроить код согласно вашему требованию. Установите isActionsEnabled true/false для включения/выключения действий в текстовом поле.

Предпочитаю использовать

return super.canPerformAction(action, withSender: sender)

вместо

вернуть истину

потому что возвращение true может вызвать сбой в некоторых случаях.

Вот мой код,

open class MyTextFieldEffect : UITextField {

    var isActionsEnabled = true {
        didSet {
            reloadInputViews()
        }
    }

override open func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        /* disable particular actions
        if (action == #selector(paste(_:)) || action == #selector(copy(_:)) || action == #selector(select(_:)) || action == #selector(cut(_:)) || action == #selector(delete(_:)) || action == #selector(replace(_:withText:))  || action == #selector(select(_:))  || action == #selector(selectAll(_:)) || action == #selector(insertText(_:)) || action == #selector(draw(_:))) && !isActionsEnabled {
            return false
        }
        return super.canPerformAction(action, withSender: sender)
                                           */

       //disable all actions
        if !isActionsEnabled {
            return false
        }

        return super.canPerformAction(action, withSender: sender)
    }
}

Ответ 11

Небольшое редактирование с кодом, потому что, когда вы пытаетесь использовать любую функцию, например cut или другую, приложение будет разбиваться. Следующий код, протестированный на Swift 3 и очень хорошо работающий

override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if action == #selector(copy(_:)) || action == #selector(paste(_:)) {
            return false
        }
        return super.canPerformAction(action, withSender: sender)
    }

Ответ 12

Если вы хотите открыть представление "Выбор даты" или "Выбор" в TEXTFIELD, щелкните ниже, код работает.

Добавьте ниже два метода в вашем классе.

//Hide Menu View
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {

    if YOURTEXTFIELD.isFirstResponder {
        DispatchQueue.main.async(execute: {
            (sender as? UIMenuController)?.setMenuVisible(false, animated: false)
        })
        return false
    }

    return super.canPerformAction(action, withSender: sender)
}

//ДОЛЖНЫ Внедрить

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
            return false
}