Как отключить вставку в TextField в Swift?
У меня есть TextField
с числовой панелью, и функция запускается только в том случае, если она содержит числа.
Единственная опция, с которой пользователь будет разбивать приложение, - это вставить буквы в TextField
и нажать "ОК".
Как отключить вставку в TextField?
Ответы
Ответ 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
UIResponderStandardEditActions
были недавно добавлены (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
}