将语音添加到自定义UIMenuController

我在UIWebView创build了一个自定义的UIMenuController ,但似乎在此之后摆脱了UIMenuController中的“说话select”选项。 说话select选项在所有testing设备上的“首选项”中打开,并出现在其他应用程序中,包括非Apple应用程序。 有一个无障碍服务或sharedMenuController一部分,我可以打电话来获得这个项目?

 UIMenuItem *copyMenuItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Copy", @"Copy menu item") action:@selector(myappCopy:)]; UIMenuItem *highlightMenuItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Highlight", @"Highlight menu option") action:@selector(myappHighlight:)]; UIMenuItem *unhighlightMenuItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Remove Highlight", @"Remove Highlight menu option") action:@selector(myappRemoveHighlight:)]; UIMenuItem *noteMenuItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Note", @"Note menu options") action:@selector(myappNote:)]; [UIMenuController sharedMenuController].menuItems = [NSArray arrayWithObjects:copyMenuItem, highlightMenuItem, unhighlightMenuItem, noteMenuItem, nil]; [copyMenuItem release]; [highlightMenuItem release]; [unhighlightMenuItem release]; [noteMenuItem release]; 

我甚至试图在开始时parsing现有的共享菜单项,但是我没有看到任何东西在日志中倾倒。 该方法正在启动应用程序调用。

试过这个方法的顶部:

  for (UIMenuItem *menuItem in [UIMenuController sharedMenuController].menuItems) { NSLog(@"title: %@", menuItem.title); NSLog(@"action: %@", menuItem.action); } 

任何帮助深表感谢! 谢谢 – 埃里克

一些UIMenuController项目可以在UIKit框架中的UIResponder.h中find。

 @interface NSObject(UIResponderStandardEditActions) // these methods are not implemented in NSObject - (void)cut:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0); - (void)copy:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0); - (void)paste:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0); - (void)select:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0); - (void)selectAll:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0); - (void)delete:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_2); - (void)makeTextWritingDirectionLeftToRight:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0); - (void)makeTextWritingDirectionRightToLeft:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0); @end 

但是那里没有说文字选项。 事实certificate,如果在下面列出的UIWebView或UITextField的子类中覆盖“canPerformAction:WithSelector:”,还将获得发送给自我的所有操作(包括UIMenuController选项)的列表。

 // Override - (BOOL) canPerformAction:(SEL)action withSender:(id)sender { NSLog(@"%@",NSStringFromSelector(action)); //if you are customizing your menu, return NO except for your specific selectors return YES; } 

你会发现几个你可能感兴趣的方法,包括_accessibilitySpeak:和_accessibilityPauseSpeaking:_define :(请注意这三个select器只有iOS 5)。 下划线表示它们是私有的,所以也要记住,不能用经典的[类select器]语法直接调用它们。

请记住,这些是系统菜单项,这意味着苹果会将它们粘贴在您添加的任何菜单项的前面,通常通过点击>箭头将菜单项留在第二层中。 如果您想要控制项目的显示顺序和/或将Apple的系统项目与项目混合在一起,则需要为这些在类中调用方法的操作创build自定义菜单项,如下所示:

 - (void) myAppSpeak: (UIMenuController*) sender { [super performSelector:@selector(_accessibilitySpeak:)]; } 

请记住,这些方法需要在实现这些方法的类的子类中实现,例如UIWebView的子类…而不是UIWebViewController的子类。

然后在控制器内部或者在你build立你的UIMenuController的地方,创build调用这个方法的自定义button。 确定如果你在networking视图中,你引用了你的子类的types的对象,而不是通用的web视图。 否则,它将无法正常工作。

  UIMenuItem *speakMenuItem = [[UIMenuItem alloc] initWithTitle:@"Speak" action:@selector(myAppSpeak:)]; [UIMenuController sharedMenuController].menuItems = [NSArray arrayWithObjects:speakMenuItem, etc. etc., nil]; 

即使将它添加到菜单项中,也不会出现,除非您在canPerformAction中select器返回YES:WithSelector:在您的Web视图或文本字段的子类中。 所以请随时在这里添加项目,否则可能是情况。 你可以在你的子类视图中使用逻辑来sorting。

我发现这个bug有一些有趣的事情。 基本上,当说select启用时,在你做第一个select之后, UIMenuController被清空menuItems 。 解决scheme尽pipe很简单,但很简单。

 - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { NSString *selectorString = NSStringFromSelector(action); BOOL isAccessibilitySelector = [selectorString isEqualToString:@"_accessibilitySpeak:"] || [selectorString isEqualToString:@"_accessibilityPauseSpeaking:"]; if (isAccessibilitySelector && [super canPerformAction:action withSender:sender]) { //(re)add menuItems to UIMenuController return YES; } return NO; 

}

我应该注意到,在canPerformAction...()被调用之后,你必须重新添加menuItems

我已经提交这个雷达:12931434。 更新:DUP为13060693 。