複数のカスタムメニュー項目を追加したときに「More ...」ラベルが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>.
リンクしたテクニックはまだ機能しているようです。これらのメソッドを使用して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;
}
for ios> = 5.1 canPerformAction:(SEL)action withSender:(id)senderが機能しなくなりました。
貼り付けアクションを無効にするだけで問題がない場合は、次の方法があります。
uITextFieldDelegateをビューコントローラーに追加し、次のようなメソッドを実装します
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if(textField == txtEmailRe)
return ((string.length) > 1 ? NO : YES);
}
これは、ユーザーがアクションごとに複数の文字を入力した場合(おそらくユーザーが何かを貼り付けていることを意味します)、テキストフィールドでそれを受け入れないことを意味します。
ユーザーに電子メールやメールなどのテキストフィールドを強制的に入力することをお勧めします。
これが私のために働くiOS5.xのための解決策です。これはJoshGarnhamによるもので、コピー:、貼り付け:、定義:セレクターをキャッチするためにUIWebBrowserViewカテゴリを作成することを提案しています。
@implementation UIWebBrowserView (UIWebBrowserView_Additions)
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
return NO;
}
@end
FTRだけに注意してください:その優れたWebページにはわずかなタイプミスがあります。これがまさにあなたがそれをする方法です。 Apple will100%これを拒否します。カテゴリを作成します
(Xcodeはプライベートクラスを表示しないため、「UIWebBrowserView」と入力する必要があります。)。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
ちなみに、「シングルクリック」でも迷惑なスペルチェッカーの提案が表示されます。ただし、それ以外の場合は、ダブルクリックのコンテキストメニューが完全に削除され、Appleによって100%拒否されます。
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を使用します。
[〜#〜]更新[〜#〜]:
「コピー」を無効にしたいが、「定義」(および「翻訳」)を残したい場合は、これが便利な方法です。上記の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];
}
英語でごめんなさい。しかし、アイデアがあります。
CanPerformActionメソッドは何度も呼び出されたと思いますが、一度処理するだけです。この場合、別のUIコントロールがそれを呼び出している可能性があると思います。たとえば、UIWebViewのUITextViewコントロール。
ストーリーボードでUIを生成できると思います。ストーリーボードのすべてのコントロールに独自のクラスがあるわけではありません。応答コントロールのクラスを定義し、そのcanPerformActionメソッドを書き直すことができます。
UIMenuControllerを使用する代わりに、独自のメニューを描画することもできます。そうすれば、Otherを使用せずに、必要な数のアイテムを同時に表示できます。