13

シェイクイベントをキャプチャするために(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)eventを使用しようとすると、少し問題が発生します。問題は、canBecomeFirstResponderをオーバーライドして、YESを返すように設定しても、関数が実行されていないことです。この問題に関する他の人の投稿を見たことがありますが、答えは見つかりませんでした。

助けてくれてありがとう!

最初の例.h(UIViewから継承されたクラス-アプリデリゲートクラスから「呼び出された」){

@class TestApplicationView;

@interface TestApplicationView : UIView {

    IBOutlet UIView *view;
}

}

最初の例.m{

- (id)initWithCoder:(NSCoder *)coder
{
    [self setUpView];
    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    [self setUpView];
    return self;
}

- (void)setUpView
{
    [self becomeFirstResponder];
    NSLog(@"First Responder - %d", [self isFirstResponder]);
}

}

2番目の例.h(UIApplicationDelegateおよびUIScrollViewDelegateから継承されたクラス){

#import <UIKit/UIKit.h>

@class TestApplicationViewController;

@interface TestApplicationAppDelegate : NSObject <UIApplicationDelegate, UIScrollViewDelegate> {

IBOutlet UIWindow *window;
IBOutlet UIScrollView *scrollView;
}

}

2番目の例.m{

- (void)applicationDidFinishLaunching:(UIApplication *)application
{
    [self becomeFirstResponder];
}

}

--2番目の例は、次の警告を返します。'TestApplicationAppDelegate'は'-becomeFirstResponder'に応答しない可能性があります

4

2 に答える 2

31

これをのサブクラスに実装したいと思いますUIViewController。ファーストレスポンダーUIViewControllerになれるようにする:

- (BOOL)canBecomeFirstResponder {
     return YES;
}

UIViewControllerでファーストレスポンダーになりますviewDidAppear:

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

ビューに、UITextFieldファーストレスポンダー自体になる可能性のある要素などの要素が含まれている場合は、要素がいずれかの時点でファーストレスポンダーを辞任するようにします。UITextFieldたとえば、を使用すると、プロトコルUIViewControllerを実装する必要がありUITextFieldDelegate、実際にはデリゲートになります。次に、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;
}

埋め込む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];
    }
}

AppleのMattDranceによるiPhone開発者フォーラムへの良い投稿があります(開発者としての登録が必要です)。

更新:UIViewのサブクラスでの実装

コメントで説明されているように、これは、当然のことながら、のサブクラスでも機能しUIViewます。最小限の例を作成する方法は次のとおりです。

新しいビューベースのアプリケーションプロジェクトを作成し、それを呼び出しますShakeTest。の新しいサブクラスを作成し、UIViewそれを呼び出しますShakeViewShakeView.hこのように見せてください:

#import <UIKit/UIKit.h>
@interface ShakeView : UIView {
}
@end

ShakeView.mこのように見せてください:

#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

ShakeTestViewController.hこのように見せてください:

#import <UIKit/UIKit.h>
#include "ShakeView.h"
@interface ShakeTestViewController : UIViewController {
    ShakeView *s;
}
@end

ShakeTestViewController.mこのように見せてください:

#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

ビルドして実行します。Cmd-Ctrl-Zを押して、iPhoneシミュレーターをシェイクします。ログメッセージに驚嘆してください。

于 2009-08-28T01:49:21.703 に答える
0

古いメソッドを実装していますか

'acelerometer:didAccelerate'

?古いアプリケーション全体のメソッドを実装している場合は、新しいメソッドを呼び出す前にそれを削除する必要があります。

于 2009-08-27T19:17:11.947 に答える