2012-03-26 231 views
7

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

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]; 

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

在方法的顶部试过这样:

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

任何帮助,非常感谢!谢谢 - 埃里克

+0

底线......所以我发现在方法开始时UIMenuController项目数组的数量为0,所以for循环毫无意义。 – 2012-03-27 14:42:32

+0

我只想知道,有谁知道如何访问默认的UIMenuController项目并将它们包含在菜单项中? – 2012-03-27 14:43:03

+0

我已将此作为雷达提交:12931434。您是否可以通过下面的解决方案获得应用商店的批准? – 2012-12-24 16:27:47

回答

7

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

@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 

但是这里没有说话的文字选项。事实证明,如果在下面列出的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:(请注意这三个选择是iOS 5中只)。下划线表示它们是私有的,所以也要记住,你不能用经典的[类选择器]语法直接调用它们。

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

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

请记住,这些方法都需要在已经实现了这些类,的一个子类来实现,例如一个子类的UIWebView的.... UIWebViewController的不是一个子类别。

然后,控制器,或任何你建立你UIMenuController中,创建调用此方法的自定义按钮。确定如果你在网络视图中,你引用了一个你的子类类型的对象,而不是通用的webview。否则,它将无法正常工作。 WithSelector:在你的Web视图或文本字段的子类

UIMenuItem *speakMenuItem = [[UIMenuItem alloc] initWithTitle:@"Speak" action:@selector(myAppSpeak:)]; 

    [UIMenuController sharedMenuController].menuItems = [NSArray arrayWithObjects:speakMenuItem, etc. etc., nil]; 

即使你将它添加到您的菜单项,它不会,除非你在你的canPerformAction选择返回YES出现。所以请随时在这里添加可能情况相反的项目。你可以在你的子类视图中使用逻辑来排序。

7

我发现这个bug有一些有趣的事情。基本上,当启用说话选择时,在做出第一个选择之后,UIMenuController被清空menuItems。这个解决方案尽管很简单,但很简单。

- (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