motionBegan: Not Working
I assume you want to implement this in a subclass of UIViewController
. Make the UIViewController
capable of becoming first responder:
- (BOOL)canBecomeFirstResponder {
return YES;
}
Make the UIViewController
become first responder in viewDidAppear:
.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self becomeFirstResponder];
}
If the view contains any element, such as a UITextField
, that might become first responder itself, ensure that element resigns first responder at some point. With a UITextField
, for example, the UIViewController
would need to implement the UITextFieldDelegate
protocol, and actually be the delegate. Then, in textFieldShouldReturn:
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
// Hides the keyboard
[theTextField resignFirstResponder];
// Returns first responder status to self so that shake events register here
[self becomeFirstResponder];
return YES;
}
Implement motionEnded:withEvent:
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if ( event.subtype == UIEventSubtypeMotionShake ) {
// Do something
}
if ([super respondsToSelector:@selector(motionEnded:withEvent:)]) {
[super motionEnded:motion withEvent:event];
}
}
There is a good post by Matt Drance of Apple in the iPhone Developer Forums (requires registration as a developer).
Update: implementing in a subclass of UIView
As discussed in the comments, this also works, not too surprisingly, in a subclass of UIView
. Here's how to construct a minimal example.
Create a new View-based Application project, call it ShakeTest
. Create a new subclass of UIView
, call it ShakeView
. Make ShakeView.h
look like this:
#import <UIKit/UIKit.h>
@interface ShakeView : UIView {
}
@end
Make ShakeView.m
look like this:
#import "ShakeView.h"
@implementation ShakeView
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if ( event.subtype == UIEventSubtypeMotionShake ) {
NSLog(@"Shake!");
}
if ([super respondsToSelector:@selector(motionEnded:withEvent:)]) {
[super motionEnded:motion withEvent:event];
}
}
@end
Make ShakeTestViewController.h
look like this:
#import <UIKit/UIKit.h>
#include "ShakeView.h"
@interface ShakeTestViewController : UIViewController {
ShakeView *s;
}
@end
Make ShakeTestViewController.m
look like this:
#import "ShakeTestViewController.h"
@implementation ShakeTestViewController
- (void)viewDidLoad {
[super viewDidLoad];
s = [[ShakeView alloc] init];
[[self view] addSubview:s];
[s becomeFirstResponder];
}
- (void)dealloc {
[s release];
[super dealloc];
}
@end
Build and run. Hit Cmd-Ctrl-Z to shake the iPhone simulator. Marvel at the log message.