Подтвердить что ты не робот

Как вы ДЕЙСТВИТЕЛЬНО удалите Копировать из 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>.
4b9b3361

Ответ 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.