0

In my Cocoa app, I have a window that contains an NSTextField (as is) and an NSScrollView (sub-classed). I've got an NSViewController that manages the window's NSView containing the text field and scrolling view.

At app startup, the NSTextField has focus, and typing enters characters into that text box. When I hit the TAB key, it loses focus. But nothing else in the interface, like the NSScrollView, gains focus. I can't tell where any key down events are going.

How does one transfer focus to the NSScrollView, so that key down events can affect it (e.g., arrow keys, implicit searching, etc.)?

jsbox
  • 304
  • 2
  • 11

1 Answers1

1

First, you should try hitting Tab repeatedly to see if focus ever makes it to the scroll view or comes back around to the text field.

You don't say what's in the scroll view as the document view. Rather than having the scroll view itself accept focus, it's more common that the document view or one of its descendant views accepts focus. Then, the movement keys would be delivered to that and, if nothing consumes them, they'd bubble up the responder chain to the scroll view and it would handle them automatically.

If you really want your scroll view to accept focus, you need to override the -acceptsFirstResponder method to return YES.

The behavior of Tab is governed by the window. It maintains a key view loop. It can automatically recalculate the key view loop as views are added and removed. That's probably the most reliable way. See the autorecalculatesKeyViewLoop property.

Alternatively, you can manually tell it to recalculate as you desire, by turning off autorecalculatesKeyViewLoop and calling -recalculateKeyViewLoop.

Or, you can explicitly set up the key view loop yourself by connecting each view's nextKeyView and previousKeyView properties, either in code or in Interface Builder.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • When there are several sub-views in the scrolling view (document view), but none of them have any sub-sub-views, focus never leaves the text editing field. But when a couple of the sub-views have sub-sub-views (vanilla NSViews) , then hitting TAB repeatedly never shows any focus on the scroll view, but does eventually get back to the text edit field. The cycle length appears to be related to the number of sub-sub-views. – jsbox Dec 07 '16 at 19:49
  • Turning off "acceptsFirstResponder" in the sub-sub-views cleaned the situation up. Turns out that they still accept mouseDown events, which was why I thought "acceptsFirstResponder" should be set to YES for them. But setting "acceptsFirstResponder" for the scroll view doesn't appear to change any default behavior, so that's still a mystery. – jsbox Dec 07 '16 at 20:20
  • How are you determining that the scroll view isn't getting focus? Have you tried changing its `focusRingType`? It might be defaulting to none, so there'd be no visual change. Anyway, as I say, it's more typical for the document view itself to accept focus. For example, when a table view is inside a scroll view, it's the table view that accepts focus, not the scroll view. – Ken Thomases Dec 07 '16 at 23:55