Как я могу реагировать на клавиши со стрелками на внешней клавиатуре?

Я знаю, что об этом уже спрашивали, и единственный ответ, который я видел, это «Не требуется внешняя клавиатура, так как это противоречит рекомендациям по пользовательскому интерфейсу». Однако я хочу использовать такую ​​педаль: http://www.bilila.com/page_turner_for_ipad для переключения между страницами в моем приложении (в дополнение к смахиванию). Этот перелистыватель страниц эмулирует клавиатуру и использует клавиши со стрелками вверх/вниз.

Итак, вот мой вопрос: как мне реагировать на эти события клавиш со стрелками? Это должно быть возможно, поскольку другие приложения управляются, но я ничего не понимаю.


person colincameron    schedule 02.11.2011    source источник


Ответы (2)


Для тех, кто ищет решение под iOS 7 — есть новое свойство UIResponder под названием keyCommands. Создайте подкласс UITextView и реализуйте keyCommands следующим образом...

@implementation ArrowKeyTextView

- (id) initWithFrame: (CGRect) frame
{
    self = [super initWithFrame:frame];
    if (self) {
    }
    return self;
}

- (NSArray *) keyCommands
{
    UIKeyCommand *upArrow = [UIKeyCommand keyCommandWithInput: UIKeyInputUpArrow modifierFlags: 0 action: @selector(upArrow:)];
    UIKeyCommand *downArrow = [UIKeyCommand keyCommandWithInput: UIKeyInputDownArrow modifierFlags: 0 action: @selector(downArrow:)];
    UIKeyCommand *leftArrow = [UIKeyCommand keyCommandWithInput: UIKeyInputLeftArrow modifierFlags: 0 action: @selector(leftArrow:)];
    UIKeyCommand *rightArrow = [UIKeyCommand keyCommandWithInput: UIKeyInputRightArrow modifierFlags: 0 action: @selector(rightArrow:)];
    return [[NSArray alloc] initWithObjects: upArrow, downArrow, leftArrow, rightArrow, nil];
}

- (void) upArrow: (UIKeyCommand *) keyCommand
{

}

- (void) downArrow: (UIKeyCommand *) keyCommand
{

}

- (void) leftArrow: (UIKeyCommand *) keyCommand
{

}

- (void) rightArrow: (UIKeyCommand *) keyCommand
{

}
person amergin    schedule 26.10.2013
comment
@Altaveron свойство keyCommands является свойством UIResponder, а UIWebView наследуется от UIResponder, поэтому я не вижу причин, по которым оно не будет работать. - person amergin; 04.01.2014
comment
@Altaveron Вы пробовали это с UIWebView, и если да, то какой результат вы видите? - person amergin; 05.01.2014
comment
Это потрясающе! Но как получить непрерывный ввод? Скажем, пользователь держит клавишу нажатой, и мы хотим определить, что нужно сделать, пока он ее не отпустит? - person Christian A. Strømmen; 09.01.2014
comment
@Christian класс UIKeyCommand не дает вам этого элемента управления, но клавиатура должна начать отправлять повторные нажатия клавиш после небольшой задержки. Если это так, то вы, вероятно, можете просто читать этот поток данных, пока он не изменится или не перестанет течь. - person amergin; 09.01.2014
comment
На UIWebView keyCommands работает, но @selectors не выполняется. Как я могу это решить? - person Dmitry; 09.01.2014
comment
Это супер полезно! Любой способ комбинировать модификаторы, например. Cmd+Shift+стрелка вправо? - person R.S; 14.01.2014
comment
Я пробовал это и только что попробовал - у меня не работает. Вы проверили это? - person R.S; 15.01.2014
comment
Извините @R.S. глупая ошибка с моей стороны, она должна читаться (UIKeyModifierCommand | UIKeyModifierShift) - это побитовое ИЛИ, а не И! - person amergin; 15.01.2014
comment
keyCommands работает, но событие вызывается как при нажатии клавиши, так и при ее отпускании. Кажется, нет никакого законного способа провести различие между ними. - person Glyn Williams; 09.03.2015

Сортировка! Я просто использую текстовое представление 1x1px и использую метод делегата textViewDidChangeSelection:

EDIT: для iOS 6 мне пришлось изменить размер текста на 50x50px (или, по крайней мере, достаточно, чтобы отображать текст), чтобы это работало

Мне также удалось подавить экранную клавиатуру при отключенной педали.

Это мой код в viewDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillAppear:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillDisappear:) name:UIKeyboardWillHideNotification object:nil];

UITextView *hiddenTextView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
[hiddenTextView setHidden:YES];
hiddenTextView.text = @"aa";
hiddenTextView.delegate = self;
hiddenTextView.selectedRange = NSMakeRange(1, 0);
[self.view addSubview:hiddenTextView];

[hiddenTextView becomeFirstResponder];
if (keyboardShown)
    [hiddenTextView resignFirstResponder];

keyboardShown объявлен как bool в моем заголовочном файле.

Затем добавьте эти методы:

- (void)textViewDidChangeSelection:(UITextView *)textView {

    /******TEXT FIELD CARET CHANGED******/

    if (textView.selectedRange.location == 2) {

        // End of text - down arrow pressed
        textView.selectedRange = NSMakeRange(1, 0);

    } else if (textView.selectedRange.location == 0) {

        // Beginning of text - up arrow pressed
        textView.selectedRange = NSMakeRange(1, 0);

    }

    //  Check if text has changed and replace with original
    if (![textView.text isEqualToString:@"aa"])
        textView.text = @"aa";
}

- (void)keyboardWillAppear:(NSNotification *)aNotification {
    keyboardShown = YES;
}

- (void)keyboardWillDisappear:(NSNotification *)aNotification {
    keyboardShown = NO;
}

Я надеюсь, что этот код поможет кому-то еще, кто ищет решение этой проблемы. Не стесняйтесь использовать его.

person colincameron    schedule 07.11.2011
comment
У меня отлично сработало, но мне пришлось поместить код инициализации в viewDidAppear, а не в viewDidLoad. - person Bryan; 18.08.2012
comment
Я думаю, что это приводит к бесконечному циклу, потому что установка свойства selectedRangetextViewDidChangeSelection) запускает другое textViewDidChangeSelection, хотя эта идея мне очень помогла. - person Bianca Daniciuc; 12.07.2013
comment
Это не приведет к бесконечному циклу, так как selectedRange устанавливается только в том случае, если положение курсора равно 0 или 2. - person colincameron; 15.07.2013
comment
Я понимаю, что это старо, но на случай, если кто-то еще столкнется с этим - есть лучший способ скрыть клавиатуру в представлении ввода, подобном этому. Просто добавьте строку: textView.inputView = [[UIView alloc] initWithFrame:CGRectZero]; - person Gabriel; 08.11.2013
comment
Хорошая идея. Но он реагирует на все клавиши, а мне нужны только клавиши со стрелками влево и вправо. - person zinnuree; 19.11.2014