I\'ve got a TextField
with a numberPad
and the function runs only if it contains numbers.
The user will crash the app if they paste letters
Swift 5
If you want to block paste action from every text field in your app
extension UITextField {
override open func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return action == #selector(UIResponderStandardEditActions.paste(_:)) ?
false : super.canPerformAction(action, withSender: sender)
}
}
EDIT
If you want to block the paste action for text fields that have pickers as input view, add a guard
like the following:
extension UITextField {
override open func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
guard inputView != nil else { return super.canPerformAction(action, withSender: sender) }
return action == #selector(UIResponderStandardEditActions.paste(_:)) ?
false : super.canPerformAction(action, withSender: sender)
}
}
Warning: the second solution will allow the user to paste on numeric fields.
I agree with Leonardo Savio Dabus, if I were you I'd use string checking and just give out a warning, it makes things easier. BUT, if disabling paste option is a fancy feature you really want to put into your app, then you need to do more work. I'll provide the steps below.
Step 1: You need to create another class which extends the UITextField
. In this example, I made my CustomUITextField
.
import Foundation
import UIKit //Don't forget this
class CustomUITextField: UITextField {
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(UIResponderStandardEditActions.paste(_:)) {
return false
}
return super.canPerformAction(action, withSender: sender)
}
}
Step 2: Wire the storyboard with your ViewController. You need to declare an IBOutlet
as in normal case:
@IBOutlet var textFieldA: CustomUITextField?
Wire the circle next to the @IBOutlet
to the TextField
in the storyboard. THEN, this is important and easy to be ignored:
TextField
CustomUITextField
Quick snapshot is provided below.
That's it, hope this works.
Credit:
Main reference
If you want to know more about the behavior of canPerformAction
method, though it's an Objective-C version, the concepts are shared here.
For Swift 3 it's changed to:
override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(copy(_:)) || action == #selector(paste(_:)) {
return false
}
return true
}
If you want to Open Date Picker or Picker view on TEXTFIELD click then below code work.
Add below two methods in your class.
//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)
}
//MUST Implement
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return false
}
Swift 4.1 this code is working fine with ViewController.
1) Disable all option (copy, paste, delete.....etc)
extension UITextField {
open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return false
}
}
2) Enable particular option (select, selectAll... etc)
extension UITextField {
open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return action == #selector(UIResponderStandardEditActions.select(_:)) || action == #selector(UIResponderStandardEditActions.selectAll(_:))
}
For Swift 5
UIResponderStandardEditActions has been added recently (iOS 10.0+) through which we can safely check if action is "paste" or not.
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)
}
}