8

anyone knows why UIViewController wouldn't become first responder when I run this code:

[self becomeFirstResponder];
NSLog(@"is first resp: %i",[self isFirstResponder]);

In the console, I always see the line: "is first resp: 0"

I HAVE canBecomeFirstResponder method:

- (BOOL)canBecomeFirstResponder {
return YES;
}

I don't even know where to look next....

Jay
  • 19,649
  • 38
  • 121
  • 184
Denis Masyukov
  • 2,966
  • 4
  • 25
  • 20
  • 3
    I've never used becomeFirstResponder on a UIViewController and I can't figure out why you would need to. It doesn't respond to user input, it's child views do however. – Nick Bedford Sep 24 '09 at 05:45
  • A responder object only becomes the first responder if the current responder can resign first-responder status (canResignFirstResponder) and the new responder can become first responder. Who is current First responder? – oxigen Sep 24 '09 at 08:29
  • Can I ask why is it essential that the UIViewCOntroller be the first responder? – Corey Floyd Sep 24 '09 at 13:00
  • Nick - I want to detect shakes (with motionEnded method which is sent to first responder only) Oxigen - I didn't check that, I'll do it. Corey - As I told to Nick, I need to receive motionEnded message somewhere, and since I chose UIViewController, I need it to be first responder for that – Denis Masyukov Sep 24 '09 at 15:44
  • The undo functionality seems to require the VC to become first responder too. At least that's how I read it, and got it to work. – mahboudz Sep 24 '09 at 16:09

3 Answers3

6

Make sure you set your UIViewController to be first responder after you have assigned some view to your window instance.

fimbaz
  • 61
  • 1
  • 1
  • 1
    NUGGET OF USEFUL INFORMATION ABOVE! Calling [self resignFirstResponder] on my view controller was failing because I had already removed its view from the screen – Kenny Winker Nov 26 '10 at 22:43
5

Update

As I suspected, I assumed wrong about UIViewController/firstResponder usage. This thread in the apple dev forums talks specifically about getting shaking to work.

Original Answer

Call becomeFirstResponder on the UI element that you want to respond. The events will automatically get forwarded to the UIViewController as long as no other objects in the chain implement the touches methods (or at least keep forwarding them up the chain).

Side note: To build on the comments of others, it really doesn't make sense for a UIViewController to be the "first" responder. The first responder should be an object with an on screen representation (a UIView or one of its subclasses).

Although this may be a completely incorrect statement, there may be undocumented behavior in UIViewController that prevents it from becoming the firstResponder because of these issues (Someone smarter than me may be able to verify the validity of this).

picciano
  • 22,341
  • 9
  • 69
  • 82
Corey Floyd
  • 25,929
  • 31
  • 126
  • 154
  • I agree with you, but how else would you add shake-detection functionality? I can have the method in one of the UIView subclasses, but how can I guarantee that I will always detect shakes unless the method is in the most parent class? – Denis Masyukov Sep 24 '09 at 15:48
  • Good point, i updated my answer with some information I found in the dev forums – Corey Floyd Sep 24 '09 at 17:28
  • 1
    Corey, it worked. The key was to make VC first responder in ViewDidAppear. – Denis Masyukov Sep 24 '09 at 18:07
  • Now I can only detect shakes on startup. I have UIScrollView with bunch of nested UIViews, and it is still a challenge to make them detect shakes as well.... :( – Denis Masyukov Sep 24 '09 at 18:11
  • You may have to override the motion began/ended methods in the subviews or at least the scrollview as well and handle the forwarding manually. Passing events passing through UIScrollView has been tricky, it generally likes to swallow (touch) events. Not sure about motion events. – Corey Floyd Sep 24 '09 at 22:36
4

Do you have a UIScrollView in that UIViewController?

mahboudz
  • 39,196
  • 16
  • 97
  • 124
  • I believe that UIScrollView is taking your firstResponder status away since it wants to get the tap before it is passed on. For all intents and purposes though, I think you're fine since the shake detection mechanism will go through the UIScrollView to your view controller if it needs to. – mahboudz Sep 24 '09 at 16:05
  • that's the point - I can't detect shakes anywhere in the code. I started to dig in it and found that VC doesn't become first responder – Denis Masyukov Sep 24 '09 at 16:57