motionBegan: Not Working

混江龙づ霸主 提交于 2019-11-27 06:46:22

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.

Do you have the old method implemented? If you have the old application wide method implemented, you need to remove it before the new one will be called.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!