没有粘贴:canPerformAction:withSender 中的操作:
No paste: action in canPerformAction:withSender:
我试图强行隐藏 UITextField
上的粘贴气泡。
我的实现是从 UIResponderStandardEditActions
中指定禁止选择器的列表,将其存储在 UIResponder
类别的 AssociatedValue 中,如果在列表中找到操作,则过早退出类别的 canPerformAction:withSender:
。这是一种非常诱人的方法,因为它可以控制项目中的任何 Responder。
问题是,当我点击 UITextField
内部时,没有 paste:
操作到达整个响应链的任何 canPerformAction:withSender:
方法。我在 UIResponder
上写了一个类别,然后在 canPerformAction:withSender:
那里混了,所以我可以确定:
- (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;
}
我的层次结构的全部内容是:
cut:
copy:
select:
selectAll:
delete:
_promptForReplace:
_transliterateChinese:
_insertDrawing:
_showTextStyleOptions:
_lookup:
_define:
_define:
_addShortcut:
_accessibilitySpeak:
_accessibilitySpeakLanguageSelection:
_accessibilityPauseSpeaking:
_share:
makeTextWritingDirectionLeftToRight:
禁止_promptForReplace:
没有帮助。另外,我的 TextField 没有实现 canPerformAction:withSender:
.
那么,我应该怎么做才能找到并隐藏那个令人讨厌的粘贴?
所以在swift我会这样做:
UIMenuController.shared.menuItems?.removeAll(where: {[=10=].title == "paste"})
在 objective-c 中,您可以尝试这样的操作:
UIMenuController * controller = [UIMenuController sharedMenuController];
NSArray * items = [controller menuItems]; // These are all custom items you added
NSMutableArray * finalItemsYouWant = [NSMutableArray array];
// Here you can check what items you don't want and then remove it
[controller setMenuItems:finalItemsYouWant];
所以试着找出所有的菜单项并强行删除你想要的那个
在 UITextField
而不是 UIResponder
上创建类别成功了。
子类化 UITextField
和实现 canPerformAction:withSender:
都可以。
事实证明,UIResponder 上的类别不会影响 UITextField
上的 canPerformAction:withSender:
,即使 UITextField
IS-A UIResponder
。我不知道这是 iOS 中的一个错误还是它的内部行为有些奇怪。
我的错是太依赖调配了。我不建议您使用这种 "universal" 方法,例如创建一个包含 "prohibited" 操作选择器列表的类别以与任何响应者一起使用。
我试图强行隐藏 UITextField
上的粘贴气泡。
我的实现是从 UIResponderStandardEditActions
中指定禁止选择器的列表,将其存储在 UIResponder
类别的 AssociatedValue 中,如果在列表中找到操作,则过早退出类别的 canPerformAction:withSender:
。这是一种非常诱人的方法,因为它可以控制项目中的任何 Responder。
问题是,当我点击 UITextField
内部时,没有 paste:
操作到达整个响应链的任何 canPerformAction:withSender:
方法。我在 UIResponder
上写了一个类别,然后在 canPerformAction:withSender:
那里混了,所以我可以确定:
- (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;
}
我的层次结构的全部内容是:
cut:
copy:
select:
selectAll:
delete:
_promptForReplace:
_transliterateChinese:
_insertDrawing:
_showTextStyleOptions:
_lookup:
_define:
_define:
_addShortcut:
_accessibilitySpeak:
_accessibilitySpeakLanguageSelection:
_accessibilityPauseSpeaking:
_share:
makeTextWritingDirectionLeftToRight:
禁止_promptForReplace:
没有帮助。另外,我的 TextField 没有实现 canPerformAction:withSender:
.
那么,我应该怎么做才能找到并隐藏那个令人讨厌的粘贴?
所以在swift我会这样做:
UIMenuController.shared.menuItems?.removeAll(where: {[=10=].title == "paste"})
在 objective-c 中,您可以尝试这样的操作:
UIMenuController * controller = [UIMenuController sharedMenuController];
NSArray * items = [controller menuItems]; // These are all custom items you added
NSMutableArray * finalItemsYouWant = [NSMutableArray array];
// Here you can check what items you don't want and then remove it
[controller setMenuItems:finalItemsYouWant];
所以试着找出所有的菜单项并强行删除你想要的那个
在 UITextField
而不是 UIResponder
上创建类别成功了。
子类化 UITextField
和实现 canPerformAction:withSender:
都可以。
事实证明,UIResponder 上的类别不会影响 UITextField
上的 canPerformAction:withSender:
,即使 UITextField
IS-A UIResponder
。我不知道这是 iOS 中的一个错误还是它的内部行为有些奇怪。
我的错是太依赖调配了。我不建议您使用这种 "universal" 方法,例如创建一个包含 "prohibited" 操作选择器列表的类别以与任何响应者一起使用。