0
votes

I'm trying to detect a shake on the iPhone device, so for what i've read I need to set my view controller as first responder on the viewDidAppear method. This method is supposed to be called automatically, but for some reason this method is never called. Only viewDidLoad is called.

this is my code (I put only the relevant parts):

BuildHouseViewController.h:

@interface BuildHouseViewController : UIViewController {

BuildHouseViewController.m:

- (void)viewDidLoad {
[super viewDidLoad];
[self.view becomeFirstResponder];}

-(void)viewDidAppear:(BOOL)animated{
[self becomeFirstResponder];
[super viewDidAppear:animated];}

-(BOOL)canBecomeFirstResponder {
return YES;}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{

NSLog(@"shake"); 
if ( event.subtype == UIEventSubtypeMotionShake )
{  }

if ( [super respondsToSelector:@selector(motionEnded:withEvent:)] )
    [super motionEnded:motion withEvent:event];
}

I added breakpoints on the viewDidAppear method and it is never called. Shakes are never detected, I suppose it is because as this methods are never called, so the view controller can never become first responder. I don't understand why this is happening.

Any help will be appreciated.

Edit:

I call the view from another view using:

[self.view addSubview:nextScreen.view];

The view is displayed on screen

4
Show the code (add it to the question) where BuildHouseViewController is created and displayed.user121301

4 Answers

1
votes

Thanks for the quick answers.

I've found something interesting. I tried loading the same view I'm having problems with in different ways and I'm getting different results

-As I said before if I call it from another view using:

[self.view addSubview:nextScreen.view];

viewDidLoad is never called and I cannot detect shakes.

-Now if I call it from the AppDelegate using:

[window addSubview:nextScreen.view];

viewDidLoad is called!! and I am able to detect shakes, however this solution is not possible, I should be able to call it from another view

-If I call it from another view using:

[self presentModalViewController:nextScreen animated:YES];

viewDidLoad is called!! However I don't want to use a modal view controller, but it appears to be the only solution to my problem, shakes are detected.

It is strange that the first method doesn't load the view correctly, is it a bug??

0
votes

The [self becomeFirstResponder] and the like don't actually make that become the first responder. The method gets called when the view is going to become the first responder. So that's not doing what you think it is.

Secondly, the viewDidAppear will only be called when the view, well, did appear. Is it showing up on the screen? Where are you telling it to be displayed? You need to either add the view controller's view as a subview of another view, or pushed onto a navigation controller stack, or pushed as a modal view.

0
votes

viewDidAppear:(BOOL)animated only gets called when the view is shown by UINavigationController or UITabBarController. If you add a view controller's view to a subview (such as a scrollview or what have you), it won't get called. You would think it would but you'd be wrong. Just got bit by this myself.

0
votes

Further to @Genericrich's comments, you can manually call viewDidAppear after you put the subview in yourself.

[self.view addSubview:theViewController.view];
[theViewController viewDidAppear:FALSE];

This worked for me. Hope it helps someone else.