iosobjective-cuitextfieldpasteuiresponder

No paste: action in canPerformAction:withSender:


I am trying to forcibly hide the Paste bubble on my UITextField. My implementation is to specify a list of prohibited selectors from UIResponderStandardEditActions, store it in an AssociatedValue in a UIResponder category and quit category's canPerformAction:withSender: prematurely if action is found in the list. This is quite tempting approach, because it lets to control any Responder in the project.

Problem is no paste: action reaches any canPerformAction:withSender: method for the whole responder chain when I tap inside my UITextField. I wrote a category on UIResponder and swizzled canPerformAction:withSender: there, so I can be sure:

- (BOOL)my_canPerformAction:(SEL)action withSender:(id)sender {
    NSString *string = NSStringFromSelector(action);
    BOOL prohibited = [self.prohibitedActions containsObject:string];

    if (prohibited) {
        return NO;
    }

    BOOL canPerform = [self my_canPerformAction:action withSender:sender];
    return canPerform;
}

The whole catch for my hierarchy is:

 cut:
 copy:
 select:
 selectAll:
 delete:
 _promptForReplace:
 _transliterateChinese:
 _insertDrawing:
 _showTextStyleOptions:
 _lookup:
 _define:
 _define:
 _addShortcut:
 _accessibilitySpeak:
 _accessibilitySpeakLanguageSelection:
 _accessibilityPauseSpeaking:
 _share:
 makeTextWritingDirectionLeftToRight:

Prohibiting _promptForReplace: does not help. Also, my TextField does not implement canPerformAction:withSender:.

So, what should I do to track down and hide that nasty paste?


Solution

  • Creating category on UITextField instead of UIResponder did the trick. Subclassing UITextField and implementing canPerformAction:withSender: works either.

    It turned out that category on UIResponder does not affect canPerformAction:withSender: on UITextField, even though UITextField IS-A UIResponder. I do not know whether it is a bug in iOS or some oddity in it's internal behavior.

    My fault was to rely too much on swizzling. I do not recommend you this "universal" approach like making a category with a list of "prohibited" action selectors to work with any responder.