I am trying to restrict cut, copy, paste, share in text-filed. By using below code i am able to restrict cut, copy & paste but not sure how to restrict share option.
is there any way to do that?
class RestrictedTextField: UITextField {
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(UIResponderStandardEditActions.paste(_:)) || action == #selector(UIResponderStandardEditActions.copy(_:)) || action == #selector(UIResponderStandardEditActions.cut(_:)){
return false
}
return super.canPerformAction(action, withSender: sender)
}
}
Note: It's not possible for
Here is the list of all default actions:
paste:
cut:
copy:
select:
selectToHere:
selectAll:
paste:
delete:
_promptForReplace:
_transliterateChinese:
_insertDrawing:
_showTextStyleOptions:
_lookup:
_addShortcut:
_accessibilitySpeak:
_accessibilitySpeakLanguageSelection:
_accessibilityPauseSpeaking:
_share:
makeTextWritingDirectionRightToLeft:
makeTextWritingDirectionLeftToRight:
You can check for any of them if you want. But as you can see, some of theme, including _share, are private and your app will be rejected from AppStore if you touch them.
For private ones, you can do this like:
action.description == "_share:"
this method tricks AppStore auto review mechanism a bit but I'm not recommending it. 🤷🏻♂️
One thing You can do is to suppress all actions and include your needs instead:
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
let validActions = [
#selector(UIResponderStandardEditActions.toggleUnderline(_:)),
#selector(UIResponderStandardEditActions.makeTextWritingDirectionLeftToRight(_:)),
#selector(UIResponderStandardEditActions.makeTextWritingDirectionLeftToRight(_:))
]
return validActions.contains(action)
}
Note that some of the actions are forced somehow and can not be overridden easily
Related
// Subclass UITextView to remove default context menu items like Learn and Share and keep Cut, Copy and Paste
class TextView : UITextView {
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
let actions = [#selector(copy(_:)), #selector(cut(_:)), #selector(paste(_:))]
return actions.contains(action)
}
}
I've used the above code to remove excessive menu items and only keep cut/copy/paste but recently there's a new menu item called Search Web that searches the highlighted text in Safari/Google. Is there a way to disable that too?
Remove it in buildMenu(with builder:)
override func buildMenu(with builder: UIMenuBuilder) {
if builder.menu(for: .lookup) != nil {
builder.remove(menu: .lookup)
}
super.buildMenu(with: builder)
}
I'm trying to configure UIMenuController's menu items for a functionality similar to Medium's iOS feature:
There are a variety of threads devoted to this specific task, but despite tens of thousands of views and varied results, including it not working for a significant enough number of people... it doesn't seem like there is a solution that works consistently for UITextView.
I have been able to add a custom menu option "printToConsole", but I can't disable Apple's standard menu items like cut, copy, paste, B I U, etc:
The consensus seems to be that I should override canPerformAction to disable these default menu items as such, but that doesn't seem to be working:
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
print("canPerformAction being called")
if action == #selector(cut(_:)) {
return false
}
if action == #selector(copy(_:)) {
return false
}
if action == #selector(select(_:)) {
return false
}
if action == #selector(paste(_:)) {
return false
}
if action == #selector(replacementObject(for:)) {
return false
}
if action == #selector(selectAll(_:)) {
return false
}
if action == #selector(printToConsole) {
return true
}
return super.canPerformAction(action, withSender: sender)
}
This is the remainder of my relevant code:
func addCustomMenu() {
let consolePrintAction = UIMenuItem(title: "Print To Console", action: #selector(printToConsole))
UIMenuController.shared.menuItems = [consolePrintAction]
UIMenuController.shared.update()
}
#objc func printToConsole() {
if let range = articleTextView.selectedTextRange, let selectedText = articleTextView.text(in: range) {
print(selectedText)
}
}
And in my viewDidLoad:
articleTextView.delegate = self
addCustomMenu()
I've set my viewController to conform to UITextViewDelegate as well. Some are suggesting that if you simply subclass the TextView this will work somehow. I haven't been able to get that to work, so if that is truly the answer, can someone provide an example?
Again, I know this may seem like a duplicate, but the above solution appears to have stopped working with an update of iOS.
Thanks.
Going to give credit to #gaurav for his answer on this one, which must have escaped me in my hunt on SO: https://stackoverflow.com/a/46470592/7134142
The key piece of code is this, which is extending UITextView, rather than subclassing it:
extension UITextView {
open override func canPerformAction(_ action: Selector, withSender
sender: Any?) -> Bool {
return false
}
Overriding canPerformAction in my view controller was unnecessary, and the above code still allows you to add your custom menu items. This is what I ended up with:
This question already has answers here:
How to disable copy paste option from UITextField programmatically
(17 answers)
Closed 5 years ago.
The UITextField's Select, SelectAll, Cut, Copy functionality is shown by default, When I long press or Double Tap on the TextField. I do not require this all features. Please tell me how to disable long press or double tap gesture functionality.
Following code will disable those options:
You have to subclass the UITextField and try to use this code to disable/hide caret and input (copy/paste)
override func caretRectForPosition(position: UITextPosition!) -> CGRect {
return CGRect.zeroRect
}
override func selectionRectsForRange(range: UITextRange) -> [AnyObject] {
return []
}
override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
// Disable copy, select all, paste
if action == Selector("copy:") || action == Selector("selectAll:") || action == Selector("paste:") {
return false
}
// Default
return super.canPerformAction(action, withSender: sender)
}
Here is the swift 3.0 answer,
please try this,
override func canPerformAction(_ action: Selector, withSender sender: Any) -> Bool {
UIMenuController.shared.menuVisible = false
//do not display the menu
self.resignFirstResponder()
//do not allow the user to selected anything
return false
}
Hope this will help you.
iOS 10. Swift 3
I put this into my class with the UITextView. Seemed to be the best answer for removing some of the functionality in a popup menu. Initially had a issue with it crashing and I accepted and voted the answer to that question as correct... but on further testing.. I find the code simply doesn't work as intended.
Unfortunately It infact does nothing, absolutely nothing!! beyond compiling seemly catching the menu options and than doing them anyway, even if I trying to ignore them.
It seems it used to work in objective C as far as I can tell in other SO posts, but not in Swift? Has anybody managed to get a working version in Swift that looks like this perhaps, with some subtle code change I am missing here.
override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if (action == #selector(cut)) {
return false
}
return super.canPerformAction(action, withSender: sender)
}
You need to reorganize your implementation a bit. It should be:
override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if (action == #selector(delete)) {
return false
} else {
return super.canPerformAction(action, withSender: sender)
}
}
As you had it, you were ignoring the result of super.canPerformAction and always returning true. That's bad because your class doesn't respond to every single selector.
This question already has answers here:
How to disable copy paste option from UITextField programmatically
(17 answers)
Closed 7 years ago.
I want to remove the option "Paste" from the selector
I've tried the code below but it adds other selections to the selector and the paste option is still there, it just disables the functionality
override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
if action == "paste:" {
return false
}
return true
}
I want to remove Paste all together so the user doesn't even have the option to see it or click it
Have a look at UIMenuController
You should be able to use
var menuItems: [AnyObject]?
to set up your own object.
It is not a simple switch on or off the existing buttons, looks like you have to provide your own.
try this :
Step 1: You need to create another class which extends the UITextField. In this example, I made my CustomizedUITextField.
import UIKit
class CustomTextField: UITextField {
override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
if action == "paste:" {
return false
}
return super.canPerformAction(action, withSender: sender)
}
}