Alex Rivera | Logout

Is there any way of asking an iOS view which of its children has first responder status?

Asked 2011-02-17T13:02:18.483
45

In Mac OS X, you can find the first responder like this:

[[self window] firstResponder]

Is there any way of doing it in iOS? Or do you need to enumerate the child controls and send an isFirstRespondermessage to each one?

Edit
Report

1 Answer

255

I really like VJK's solution, but as MattDiPasquale suggests it seems more complex than necessary. So I wrote this simpler version:

Objective-C

UIResponder+FirstResponder.h:

#import <UIKit/UIKit.h>

@interface UIResponder (FirstResponder)
    +(id)currentFirstResponder;
@end

UIResponder+FirstResponder.m:

#import "UIResponder+FirstResponder.h"

static __weak id currentFirstResponder;

@implementation UIResponder (FirstResponder)

+(id)currentFirstResponder {
    currentFirstResponder = nil;
    [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:) to:nil from:nil forEvent:nil];
    return currentFirstResponder;
}

-(void)findFirstResponder:(id)sender {
   currentFirstResponder = self;
}

@end

Swift 4

import UIKit

extension UIResponder {

    private static weak var _currentFirstResponder: UIResponder?

    static var currentFirstResponder: UIResponder? {
        _currentFirstResponder = nil
        UIApplication.shared.sendAction(#selector(UIResponder.findFirstResponder(_:)), to: nil, from: nil, for: nil)

        return _currentFirstResponder
    }

    @objc func findFirstResponder(_ sender: Any) {
        UIResponder._currentFirstResponder = self
    }
}

I also made it a class method since that seemed to make more sense. You can now find the first responder like so: [UIResponder currentFirstResponder]


Note: This does not always work. For example after you init a UIImagePickerController, UIResponder.currentFirstResponder returns nil. If you need this use https://stackoverflow.com/a/50472291/3393964

<
answered 2013-01-03T08:40:31.877

Your Answer