Как вы ДЕЙСТВИТЕЛЬНО удалите Копировать из UIMenuController
Там, по-видимому, обычно был простой способ, чтобы предотвратить появление ярлыка "Больше..." в UIMenuController, когда вы добавили несколько отдельных элементов меню. Вам просто нужно было удалить все элементы системного меню. Был даже обходной путь здесь для работы с копиями. Вам просто нужно было выполнить команду пользовательского копирования с помощью другого селектора, а затем переопределить canPerformAction: withSender: чтобы не отображать системную копию:
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(copy:))
return NO;
else
// logic to show or hide other things
}
К сожалению, этот метод больше не работает (по крайней мере, в подклассе UIWebView). canPerformAction: withSender: вызывается для каждого элемента системного меню, кроме копии: так что результат всегда отображается в пункте меню системной копии. Это означает, что если у вас есть несколько отдельных элементов меню, они всегда скрыты за "Подробнее..."
Итак, есть ли способ действительно удалить элемент копии системы или какой-то другой способ предотвратить скрытие элементов меню за "Подробнее..."?
Обновление
Это результат, который я получаю, когда я переопределяю canPerformAction: withSender: обратите внимание, что метод никогда не вызывается для действия "copy:":
cannot perform action cut: with sender <UIMenuController: 0x7227d30>.
cannot perform action select: with sender <UIMenuController: 0x7227d30>.
cannot perform action selectAll: with sender <UIMenuController: 0x7227d30>.
cannot perform action paste: with sender <UIMenuController: 0x7227d30>.
cannot perform action delete: with sender <UIMenuController: 0x7227d30>.
cannot perform action promptForReplace: with sender <UIMenuController: 0x7227d30>.
cannot perform action _showMoreItems: with sender <UIMenuController: 0x7227d30>.
cannot perform action _setRtoLTextDirection: with sender <UIMenuController: 0x7227d30>.
cannot perform action _setLtoRTextDirection: with sender <UIMenuController: 0x7227d30>.
can perform action customCopy: with sender <UIMenuController: 0x7227d30>.
can perform action custom1: with sender <UIMenuController: 0x7227d30>.
cannot perform action custom2: with sender <UIMenuController: 0x7227d30>.
can perform action custom3: with sender <UIMenuController: 0x7227d30>.
can perform action custom4: with sender <UIMenuController: 0x7227d30>.
cannot perform action cut: with sender <UIMenuController: 0x7227d30>.
cannot perform action select: with sender <UIMenuController: 0x7227d30>.
cannot perform action selectAll: with sender <UIMenuController: 0x7227d30>.
cannot perform action paste: with sender <UIMenuController: 0x7227d30>.
cannot perform action delete: with sender <UIMenuController: 0x7227d30>.
cannot perform action promptForReplace: with sender <UIMenuController: 0x7227d30>.
cannot perform action _showMoreItems: with sender <UIMenuController: 0x7227d30>.
cannot perform action _setRtoLTextDirection: with sender <UIMenuController: 0x7227d30>.
cannot perform action _setLtoRTextDirection: with sender <UIMenuController: 0x7227d30>.
Ответы
Ответ 1
Техника, с которой вы связаны, по-прежнему работает. Я реализовал подкласс UIWebView
с этими методами, и появились только элементы A и B.
+ (void)initialize
{
UIMenuItem *itemA = [[UIMenuItem alloc] initWithTitle:@"A" action:@selector(a:)];
UIMenuItem *itemB = [[UIMenuItem alloc] initWithTitle:@"B" action:@selector(b:)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObjects:itemA, itemB, nil]];
[itemA release];
[itemB release];
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
BOOL can = [super canPerformAction:action withSender:sender];
if (action == @selector(a:) || action == @selector(b:))
{
can = YES;
}
if (action == @selector(copy:))
{
can = NO;
}
NSLog(@"%@ perform action %@ with sender %@.", can ? @"can" : @"cannot", NSStringFromSelector(action), sender);
return can;
}
Ответ 2
для ios >= 5.1 canPerformAction: (SEL) действие с Sender: (id) отправитель больше не работает.
Если вы в порядке, просто отключите действие вставки, это метод:
добавьте UITextFieldDelegate, чтобы просмотреть контроллер и реализовать метод, подобный этому
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if(textField == txtEmailRe)
return ((string.length) > 1 ? NO : YES);
}
это означает, что если пользователь вводит более одного символа для каждого действия (это означает, что, вероятно, пользователь вставляет что-то.) не принимает его в текстовом поле.
Это хорошая практика для пользователя с полномочиями вводить текстовые поля, такие как электронная почта и
Ответ 3
lemnar ответ правильный. Реализация подкласса UIWebView работает очень хорошо. Этот пример подходит для UITextView. Для UIWebView создайте собственный подкласс следующим образом:
//
// MyUIWebView.h
//
#import <UIKit/UIKit.h>
@interface MyUIWebView : UIWebView
@end
и
//
// MyUIWebView.m
//
#import "MyUIWebView.h"
@implementation MyUIWebView
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(copy:))
return NO;
else
// logic to show or hide other things
}
@end
Затем вместо создания экземпляра UIWebView используйте MyUIWebView.
UPDATE
Если вы хотите отключить "копию", но оставьте "define" (и "translate" ), который может быть полезен, вот как это сделать; замените canPerformAction:withSender
выше на это:
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(defineSelection:))
{
return YES;
}
else if (action == @selector(translateSelection:))
{
return YES;
}
else if (action == @selector(copy:))
{
return NO;
}
return [super canPerformAction:action withSender:sender];
}
Ответ 4
Вот решение для iOS5.x, которое работает для меня. Это Джош Гарнем, предлагая создать категорию UIWebBrowserView, чтобы поймать копию:, paste:, define: selectors.
http://ios-blog.co.uk/iphone-development-tutorials/rich-text-editing-highlighting-and-uimenucontroller-part-3/
@implementation UIWebBrowserView (UIWebBrowserView_Additions)
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
return NO;
}
@end
Отметьте только FTR: Там есть небольшая опечатка на этой превосходной веб-странице. Вот как именно вы это делаете. Apple будет 100% отклонить это. Сделать категорию
![enter image description here]()
(Вы должны ввести "UIWebBrowserView", поскольку Xcode не будет создавать частные классы.) Полный текст файлов .h и .m:
// .h file...
#import "UIWebBrowserView+Tricky.h"
@interface UIWebBrowserView : UIView
@end
@interface UIWebBrowserView(Tricky)
@end
// .m file...
#import "UIWebBrowserView+Tricky.h"
@implementation UIWebBrowserView (Tricky)
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
NSLog(@"don't let Apple see this");
return NO;
}
@end
Для записи "один клик" все равно вызовет раздражающие предложения проверки орфографии! Но в остальном он полностью удаляет контекстное меню с двойным щелчком, он на 100% отклоняется Apple.
Ответ 5
Прошу прощения за мой английский.
Но есть идея.
Я думаю, что метод canPerformAction был вызван много раз, но вы просто справляетесь с ним один раз.
В этом случае, я думаю, может быть другой UI Control назвал его. Например, элемент управления UITextView в вашем UIWebView.
Я думаю, вы можете создать пользовательский интерфейс раскадровки. Не каждый контроль в раскадровке имеет свой собственный класс. Вы можете определить класс для управления ответом и переписать его метод canPerformAction.
Ответ 6
Вы можете нарисовать свое собственное меню вместо использования UIMenuController. Таким образом, у вас может быть столько элементов, сколько вы хотите отображать в одно и то же время, не используя Other.