Как получить текущий первый ответчик из оконного контроллера в Cocoa?

Я хотел бы найти вид первого ответчика в окне. Для этого я хотел бы реализовать такую ​​категорию:

    @implementation  NSView (ViewExtensions)
- (NSView *)findFirstResponder
{
    if ([self isFirstResponder]) {        
        return self;     
    }

    for (NSView *subView in [self subviews]) {
        NSView *firstResponder = [subView findFirstResponder];

        if (firstResponder != nil) {
            return firstResponder;
        }
    }

    return nil;
}

@end

Приведенный выше код основан на этом вопросе/ответе на SO: Получить текущую службу быстрого реагирования без использования частного API.

Проблема, возможно, в том, что у NSResponder нет метода isFirstResponder, как у UIResponder. Что эквивалентно NSResponder?

Если описанный выше метод реализован так, как указано выше, я, конечно, получаю отладочное сообщение: «'NSView' может не отвечать на 'isFirstResponder'».

Как заставить findFirstResponder работать в Cocoa?

Дополнительная информация: позже я хотел бы использовать вышеуказанный метод в своем оконном контроллере, например:

        NSArray *copiedObjects;
        if ([[self window]contentView] == MyTableView) {
            copiedObjects = [tableController selectedObjects];
        }
        if ([[self window]contentView] == MyOutlineView) {
            copiedObjects = [treeController selectedFolders];
        }

person A A    schedule 10.06.2012    source источник


Ответы (2)


Что не так с -[NSWindow firstResponder], который напрямую возвращает первого ответчика?

person Ken Thomases    schedule 10.06.2012
comment
-[NSWindow firstResponder] возвращает NSResponder. Как мне получить NSView, который первым ответит? Затем я мог бы сделать if (firsResponderView == MyTableView), т.е. проверить, является ли представление текущим первым ответчиком? - person A A; 10.06.2012
comment
Представление является ответчиком — NSView наследуется от NSResponder. Итак, ваше утверждение if будет работать. В общем случае можно сделать if ([firstResponder isKindOfClass:[NSView class]]) { NSView* firstResponderView = (NSView*)firstResponder; /* do something with firstResponderView */ }. - person Ken Thomases; 10.06.2012

Если вам просто нужен первый ответчик, используйте метод firstResponder для NSWindow.

Возможно, вы захотите использовать метод NSApplications targetForAction:, если вам нужен первый ответчик для определенного действия (например, mouseDown:)

person diederikh    schedule 10.06.2012
comment
Я не думаю, что это то, что я после. Я хотел бы, чтобы isFirstResponder работал в категории. Я действительно не ищу ответ на клик пользователя. Я только упомянул, что, поскольку, когда пользователь щелкает элемент в табличном представлении, я предполагаю, что он становится первым ответчиком. Все, что я хочу сделать, это найти первого ответчика программно. Интересно, как они это сделали здесь: stackoverflow.com/questions/1823317/ - person A A; 10.06.2012