Добавление речи в пользовательский UIMenuController
Я создал кастом UIMenuController
в UIWebView
но, кажется, избавиться от опции "Speak Selection" в UIMenuController
после этого. Параметр "Разговор" включен в "Предпочтениях" на всех тестовых устройствах и отображается в других приложениях, включая приложения сторонних производителей. Есть ли служба доступности или часть 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];
Я даже пытался проанализировать существующие общие пункты меню в начале, но я не вижу ничего, что сбрасывается в журнал. Метод вызывается при запуске приложения.
Попробовал это в верхней части метода:
for (UIMenuItem *menuItem in [UIMenuController sharedMenuController].menuItems) {
NSLog(@"title: %@", menuItem.title);
NSLog(@"action: %@", menuItem.action);
}
Любая помощь высоко ценится! Спасибо - Эрик
2 ответа
Некоторые из элементов UIMenuController можно найти в UIResponder.h в UIKit Framework.
@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
Но там нет опции разговорного текста. Оказывается, если вы переопределите "canPerformAction: WithSelector:", в подклассе вашего UIWebView или UITextField, как указано ниже, вы также получите список всех действий, отправленных самому себе, включая параметры 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 будет размещать их перед любыми элементами меню, которые вы добавляете, часто оставляя доступ к элементам меню во втором слое, нажав стрелку>. Если вы хотите контролировать порядок отображения элементов и / или смешивать системные элементы Apple с вашими элементами, вам потребуется создать пользовательские элементы меню для этих действий, которые вызывают метод в вашем классе, например:
- (void) myAppSpeak: (UIMenuController*) sender
{
[super performSelector:@selector(_accessibilitySpeak:)];
}
Имейте в виду, что эти методы должны быть реализованы в подклассе класса, который их уже реализует, например, в подклассе UIWebView.... не в подклассе UIWebViewController.
Затем внутри контроллера или там, где вы строите свой UIMenuController, создайте пользовательскую кнопку, которая вызывает этот метод. Убедитесь, что если вы находитесь в веб-представлении, вы ссылаетесь на объект типа вашего подкласса, а не на общее веб-представление. Иначе это не сработает.
UIMenuItem *speakMenuItem = [[UIMenuItem alloc] initWithTitle:@"Speak" action:@selector(myAppSpeak:)];
[UIMenuController sharedMenuController].menuItems = [NSArray arrayWithObjects:speakMenuItem, etc. etc., nil];
Даже если вы добавляете его в пункты вашего меню, оно не появится, если вы не вернете YES для селектора в вашем canPerformAction: WithSelector: в вашем подклассе веб-представления или текстового поля. Так что не стесняйтесь добавлять элементы здесь, которые могут быть косвенными в противном случае. Вы можете использовать логику в своем подклассе, чтобы разобраться в этом.
Я нашел несколько интересных вещей с этой ошибкой. В основном, когда голосовой выбор включен, после того, как вы сделаете первый выбор, 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;
}
Я должен отметить, что вы должны повторно добавить menuItems
после их canPerformAction...()
был вызван.
Я представил это как радар:12931434. Обновление: DUP'ed до 13060693.