¿Cómo deshabilitar el pegado en un campo de texto en Swift?
uitextfield paste (12)
Detalles
xCode 9.1, Swift 4
Solución 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)
}
}
Solución 1 uso
let textField = UITextField(frame: CGRect(x: 50, y: 120, width: 200, height: 50))
textField.borderStyle = .roundedRect
view.addSubview(textField)
Solucion 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)
}
}
Uso de la solucion 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]
Tengo un TextField
con un teclado numérico y la función se ejecuta solo si contiene números.
La única opción de que el usuario bloquee la aplicación es si pega letras en el TextField
y hace clic en Aceptar.
¿Cómo puedo deshabilitar el pegado en el campo de texto?
Edición pequeña con un código porque cuando intentas usar cualquier función como cortar u otra, la aplicación se bloqueará. El siguiente código probado en Swift 3 y funciona muy bien
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)
}
En la versión swift real (2.2 que va a 3.0), este código de función debe ser refactorizado para:
override public func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
if action == #selector(NSObject.copy(_:)) || action == #selector(NSObject.paste(_:)) {
return false
}
return true
}
Estoy de acuerdo con Leonardo Savio Dabus, si fuera usted usaré el control de cadenas y solo daré una advertencia, hace las cosas más fáciles. PERO, si deshabilitar la opción de pegado es una característica sofisticada que realmente desea poner en su aplicación, entonces necesita hacer más trabajo. Voy a proporcionar los pasos a continuación.
Paso 1: Necesitas crear otra clase que extienda el UITextField
. En este ejemplo, hice mi 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)
}
}
Paso 2: Conecta el guión gráfico con tu ViewController. IBOutlet
declarar un IBOutlet
como en el caso normal:
@IBOutlet var textFieldA: CustomUITextField?
@IBOutlet
el círculo junto al @IBOutlet
al @IBOutlet
de texto en el guión gráfico. ENTONCES, esto es importante y fácil de ignorar:
- Ve a tu guión gráfico
- Haga clic en el campo de texto de destino
- Seleccione el inspector de identidad (el tercero)
- Cambia la clase como CustomUITextField
Instantánea rápida se proporciona a continuación.
Eso es todo, espero que esto funcione.
Crédito:
Principalmente la referencia de https://teamtreehouse.com/forum/disable-paste-in-uitextfielduitextview-swift
Si desea saber más sobre el comportamiento del método canPerformAction
, aunque es una versión de canPerformAction
-C, pero los conceptos son compartidos: ¿Cómo puedo detectar que un usuario ha pulsado un botón de formato en un UIMenuController?
He creado una clase personalizada para textField. He manejado el caso cuando desea habilitar / deshabilitar acciones en el campo de texto. Puede personalizar el código según su requisito. Configure isActionsEnabled true / false para habilitar / deshabilitar acciones en el campo de texto.
Prefiero usar
return super.canPerformAction (action, withSender: sender)
en lugar de
volver verdadero
porque devolver la verdad puede causar un bloqueo en algunos casos.
Aquí está mi código,
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)
}
}
Para Swift 3 se ha cambiado a:
override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(copy(_:)) || action == #selector(paste(_:)) {
return false
}
return true
}
Para swift3
UIResponderStandardEditActions
se han agregado recientemente (iOS 10.0+) a través de las cuales podemos verificar con seguridad si la acción es "pegar" o no.
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)
}
}
Puede crear una extensión para UITextField
y anular canPerformAction
:
override public func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
return (action != "paste:")
}
Simplemente puede adjuntar una IBAction a sus Eventos enviados (edición modificada) de su campo de texto para filtrar números que no sean de su cadena mientras escribe de la siguiente manera:
@IBAction func changedTextAction(sender: UITextField) {
sender.text = String(Array(sender.text).map{String($0)}.filter{ $0.toInt() != nil }.map{Character($0)} )
}
Swift 4.1 este código funciona bien con ViewController.
1) Deshabilitar todas las opciones (copiar, pegar, eliminar ... etc.)
extension UITextField {
open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return false
}
}
2) Habilitar la opción particular (seleccionar, seleccionarAll ... etc)
extension UITextField {
open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return action == #selector(UIResponderStandardEditActions.select(_:)) || action == #selector(UIResponderStandardEditActions.selectAll(_:))
}
Si desea abrir el Selector de fechas o la vista del Selector en TEXTFIELD, haga clic en el código siguiente.
Agregue a continuación dos métodos en su clase.
//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)
}
// DEBE Implementar
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return false
}
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
}
}