Как вы действительно удаляете копию из 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: вызывается для каждого элемента системного меню, кроме copy: поэтому в результате всегда отображается пункт меню системного копирования. Это означает, что если у вас есть несколько пользовательских пунктов меню, они всегда скрыты за "Больше..."
Итак, есть ли способ действительно удалить системный элемент копирования или какой-нибудь альтернативный способ предотвратить скрытие пунктов меню за "Больше..."?
Обновить
Это вывод, который я получаю, когда переопределяю 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>.
6 ответов
Техника, с которой вы связаны, все еще работает. Я реализовал 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;
}
Для ios >= 5.1 canPerformAction:(SEL) действие с отправителем:(id) отправитель больше не работает.
Если у вас все в порядке с просто отключить действие вставки, вот метод:
добавьте UITextFieldDelegate к своему контроллеру представления и реализуйте метод как это
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if(textField == txtEmailRe)
return ((string.length) > 1 ? NO : YES);
}
это означает, что если пользователь вводит более одного символа для каждого действия (это означает, что, вероятно, пользователь что-то вставляет.), не принимайте его в текстовом поле.
Это хорошая практика для принудительного ввода пользователем текстовых полей, таких как электронная почта и
Ответ Лемнара правильный. Реализация подкласса 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.
ОБНОВЛЕНИЕ:
Если вы хотите отключить "копировать", но оставить "определить" (и "перевести",), что может быть полезно, вот как это сделать; замещать 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];
}
Вот решение для iOS5.x, которое работает для меня. Это Джош Гарнхем, который предлагает создать категорию UIWebBrowserView для перехвата селекторов copy:, paste:, define:.
@implementation UIWebBrowserView (UIWebBrowserView_Additions)
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
return NO;
}
@end
Обратите внимание, просто FTR: на этой превосходной веб-странице есть небольшая опечатка. Вот как именно ты это делаешь. Apple на 100% отвергнет это. Сделать категорию
(Вы должны ввести "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.
Я извиняюсь за мой английский. Но есть идея.
Я думаю, что метод canPerformAction был вызван много раз, но вы просто справились с ним один раз. В этом случае, я думаю, может быть другой элемент управления пользовательского интерфейса вызвал его. Например, элемент управления UITextView в вашем UIWebView.
Я думаю, вы можете создать пользовательский интерфейс с помощью раскадровки. Не каждый элемент управления в раскадровке имеет свой собственный класс. Вы можете определить класс для элемента управления ответом и переписать его метод canPerformAction.
Вы можете нарисовать свое собственное меню вместо использования UIMenuController. Таким образом, вы можете одновременно отображать столько элементов, сколько хотите, без использования Другое.