Переход между NSTextFields с помощью nextKeyView

У меня есть один NSViewController со следующим макетом, установленным с помощью раскадровки:

Выход nextKeyView каждого из NSTextFields настроен как следующий NSTextField в порядке, представленном на снимке экрана. Например, я выбрал сервер NSTextField в ИБ и перетащил из розетки nextKeyView в Инспекторе подключений на логин NSTextField, и проделал то же самое для остальных полей.

Когда приложение запускается, любое нажатие вкладки в любом поле перемещает выделение в первое NSTextField. Как добиться желаемого табуляции между полями?

Я пробовал это в соответствующем WindowController, но безрезультатно:

- (void)windowDidLoad {
    [super windowDidLoad];

    self.window.initialFirstResponder = self.serverTextField;
}

person Dmitry Serov    schedule 12.05.2017    source источник
comment
Вы установили инициализацию первого ответа Windows?   -  person catlan    schedule 13.05.2017
comment
@catlan обновил вопрос   -  person Dmitry Serov    schedule 13.05.2017
comment
Убедитесь, что в ваших подклассах NSWindowController нет ничего -windowDidLoad. т.е. проверьте окно, self.contentViewController и текстовое поле: ViewController *vc = (ViewController *)self.contentViewController; self.window.initialFirstResponder = vc.field1;   -  person catlan    schedule 13.05.2017


Ответы (2)


Кажется, это самый подробный ответ из Джастин Бур отправил сообщение в список рассылки Coco-dev (31 января 2007 г.).

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

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

  1. Подумайте, можете ли вы согласиться на автоматически сгенерированный цикл просмотра ключей. Верхний левый угол каждого респондента определяет его место в цикле. Цикл идет сверху слева вниз справа, строка за строкой (по крайней мере, для скриптов слева направо). Это, безусловно, самое простое решение. Чтобы включить это, убедитесь, что initialFirstResponder окна имеет значение ноль. См. также -[NSWindow recalculateKeyViewLoop].

  2. Если автоматический цикл просмотра ключей не подходит, настройте свой собственный цикл просмотра ключей с помощью Interface Builder, насколько это возможно. Выход окна initialFirstResponder должен быть установлен, чтобы отключить автоматическую генерацию цикла ключей. От этого респондента вокруг цикла установите выход nextKeyView для каждого элемента в цикле. (При желании последний элемент nextKeyView может быть установлен на первый элемент, тем самым закрывая цикл.) Для любого представления с полосами прокрутки (NSTextView, NSTableView и т. д.) вы должны использовать закрывающий NSScrollView при установке nextKeyView.

  3. Если у вас есть респондеры, созданные в коде, вставьте их в цикл представления ключей заранее (желательно в awakeFromNib или, возможно, -[NSWindowController windowDidLoad]). Для каждого (последовательности) нового элемента (ов) вы должны использовать вызов -[NSView setNextKeyView:] таким образом: один раз, чтобы предыдущий элемент указывал на (первый) новый (вызовы, чтобы каждый новый элемент указывал на следующий), и, наконец, чтобы сделать так, чтобы (последний) новый элемент указывал на его преемника.

  4. Если в вашем окне есть панель инструментов, элементы панели инструментов, которые заинтересованы в том, чтобы стать основным представлением, будут автоматически добавляться и удаляться при отображении или скрытии панели инструментов. Панель инструментов не учитывает возвращаемое значение -[NSWindow autorecalculatesKeyViewLoop]. Элементы панели инструментов всегда размещаются в цикле перед самым верхним левым элементом. Нет простого способа изменить это.

  5. После того, как окно было отображено, может быть чрезвычайно сложно изменить цикл просмотра клавиш, особенно если вы используете NSScrollView или NSTabView. Это (и другие?) особые случаи, потому что они автоматически вставляют содержащиеся в них представления в цикл. Для получения информации о InitialFirstResponder и цикле просмотра ключей NSTabViewItem см. примечания к выпуску AppKit для OS X 10.1.

  6. Если у вас есть элементы, которые иногда должны быть в цикле, а иногда нет, не рекомендуется пытаться соединять их в цикле и из него. Вместо этого создайте подкласс -[NSResponder acceptsFirstResponder] для этих предметов. Если элемент возвращает NO из этого метода, он будет исключен из цикла (временно); если он возвращает YES, он возвращается в цикл. В качестве альтернативы, если элемент является производным от NSControl (вероятно, так оно и есть), вы можете вызвать для него setRefusesFirstResponder:.

  7. Если вы допустите ошибку, ваш цикл просмотра ключей перестанет функционировать либо в одном направлении, либо в обоих. Однажды сломавшись, он останется сломанным. Для отладки закомментируйте вызовы setNextKeyView: или setInitialFirstResponder:, пока они снова не заработают. Нарушающий вызов, вероятно, пытается изменить цикл представления ключа в присутствии NSScrollView или NSTabView, после того как эти объекты уже выполнили свое закулисное управление циклом. Переместите вызовы на более раннюю точку или обойдитесь без них. (Если у вас нет обращений к setNextKeyView:, то проверьте свой nib — убедитесь, что initialFirstResponder окна установлено и что nextKeyView выходы объединены в цепочку так, как вы хотите.)

  8. В Системных настройках/Клавиатура и мышь/Сочетания клавиш в нижней части панели в разделе «Полный доступ с клавиатуры» вы можете указать, включают ли циклы просмотра клавиш все элементы управления или только текстовые поля и списки прокрутки (^F7 для переключения). Вы должны протестировать свои ключевые циклы просмотра с этим параметром в каждом состоянии.

Эти рекомендации были определены экспериментально и могут быть не совсем точными. Поправки и дополнительные пояснения приветствуются.

person catlan    schedule 13.05.2017
comment
Это тщательный ответ, но он не помогает в моей ситуации. У меня есть цепочка респондентов на основе ViewController; изменение чего-либо в WindowController, похоже, не помогает. - person Dmitry Serov; 09.06.2017
comment
Стоит упомянуть свойство autorecalculatesKeyViewLoop элемента NSWindow, которое это то, что я в итоге использовал. - person aleclarson; 25.02.2019
comment
@aleclarson Вы должны превратить свой комментарий в ответ. Если вы это сделаете, я проголосую за это, потому что это также решило мои проблемы. - person jvarela; 06.01.2020

Установите initialFirstResponder окна в windowDidLoad оконного контроллера или viewWillAppear контроллера представления. Если initialFirstResponder не установлен перед makeKeyAndOrderFront окна, вызывается recalculateKeyViewLoop.

person Willeke    schedule 13.05.2017