manuelwaldner
manuelwaldner

Reputation: 561

Redirect becomeFirstResponder to a subview

Is it possible to redirect the becomeFirstResponder from self to a subview?

Here is my scenario.
I create a new UIWindow, let's call it secWin, object with a UINavigationController, let's call it navCon, as the rootViewController.
navCon has a custom UIViewController, let's call it cusViewCon, as rootViewController which contains only a single UITextField.
Now when i press a button in my main window, i call [secWin makeKeyAndVisible], which successfully shows the new window.
But now i want the UITextField to show the keyboard any time cusViewCon gets a becomeFirstResponder call, which is e.g. done by iOS by default when calling [secWin makeKeyAndVisible].

I tried to do all this by simply overwrite becomeFirstResponder in my cusViewCon class like this:

- (BOOL)becomeFirstResponder {
    [_myTextField becomeFirstResponder];

    return NO;
}

It is working, but i don't know if it is the correct way to do so, because in the documentation it says:

You can override this method in your custom responders to update your object's state or perform some action such as highlighting the selection. If you override this method, you must call super at some point in your implementation.

Upvotes: 3

Views: 2107

Answers (3)

Witek Bobrowski
Witek Bobrowski

Reputation: 4239

For those who also struggle with customisation of the responder chain in Swift, here is my take at the accepted answer. Might be useful for someone.

@discardableResult
override func becomeFirstResponder() -> Bool {
    if super.becomeFirstResponder() { return true }
    someView.becomeFirstResponder()
    return false
}
@discardableResult
override func resignFirstResponder() -> Bool {
    if super.resignFirstResponder() { return true }
    someView.resignFirstResponder()
    return false
}

someView in here is just your child view you are passing the event to. It can be UITextView, UITextField or any other UIResponder.

Upvotes: 2

Isaiah Turner
Isaiah Turner

Reputation: 2662

If you are using Swift, try this:

override func becomeFirstResponder() -> Bool {
    return super.becomeFirstResponder() || myTextField.becomeFirstResponder()
}

Upvotes: 0

Matic Oblak
Matic Oblak

Reputation: 16774

This method actually makes more sense when you code a bit for macOS where pretty much any view may become first responder. So don't worry to much about documentation.

Your procedure is on a correct track but I would do something like:

- (BOOL)becomeFirstResponder {
    BOOL willBecomeFirstResponder = [super becomeFirstResponder];
    if(willBecomeFirstResponder) {
        return YES; // This element is taking over the first responder so do nothing
    }
    else {
        [_myTextField becomeFirstResponder]; // This element may not become first responder at the moment so forward message to text field
        return NO;
    }
}

This way we ensure the execution of the superclass method still occurs. It should return false in your case (if not then also take a look into canBecomeFirstResponder method) so the text field should receive the message. If it does become first responder by design then it is best not to call it on your text field.

Upvotes: 7

Related Questions