【问题标题】:motionBegan: Not Working运动开始:不工作
【发布时间】:2010-11-23 11:34:05
【问题描述】:

当我尝试使用 (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]);
}

}

第二个例子.h(继承自 UIApplicationDelegate 和 UIScrollViewDelegate 的类) {

#import <UIKit/UIKit.h>

@class TestApplicationViewController;

@interface TestApplicationAppDelegate : NSObject <UIApplicationDelegate, UIScrollViewDelegate> {

IBOutlet UIWindow *window;
IBOutlet UIScrollView *scrollView;
}

}

第二个例子.m {

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

}

-- 第二个例子返回如下警告:'TestApplicationAppDelegate'可能不响应'-becomeFirstResponder'

【问题讨论】:

    标签: iphone cocoa cocoa-touch motion


    【解决方案1】:

    我假设你想在UIViewController 的子类中实现它。使UIViewController 能够成为第一响应者:

    - (BOOL)canBecomeFirstResponder {
         return YES;
    }
    

    UIViewController 成为viewDidAppear: 中的第一响应者。

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

    如果视图包含任何可能成为第一响应者的元素,例如UITextField,请确保该元素在某个时候退出第一响应者。例如,对于UITextFieldUIViewController 需要实现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];
        }
    }
    

    在 iPhone 开发者论坛中有一个good post by Matt Drance of Apple(需要注册为开发者)。

    更新:在 UIView 的子类中实现

    正如 cmets 中所讨论的,这在 UIView 的子类中也有效,这并不奇怪。下面是构建一个最小示例的方法。

    创建一个新的基于视图的应用程序项目,命名为ShakeTest。创建UIView 的新子类,命名为ShakeView。使ShakeView.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 模拟器。惊叹于日志消息。

    【讨论】:

    • 嗨,Paul:实际上,我在课堂上使用 UIView - 这就是它不起作用的原因吗?
    • 这不应该阻止它工作,不。您只需要执行相同的步骤:确保对象可以成为第一响应者,并确保它在摇晃事件到来时第一响应者。例如,如果子 UITextField 是第一响应者当摇晃发生时,it 将接收事件,并且由于它实现了自己的摇晃行为(摇晃以撤消),因此事件不会冒泡到您正在实现 motionEnded:withEvent 的位置:.
    • 由于某种原因,它仍然无法正常工作...我正在使用最新的 SDK,并调用 [self becomeFirstResponder];在我知道每次运行的函数中。但是,每次我尝试让该功能运行时,它都没有。是否可以在应用程序的特定点检查哪个 UIView/UITextField 是第一响应者?我认为这可能有助于我找出它没有运行的原因(如果稍后将其他元素设置为第一响应者)。
    • 它确实说,虽然 UIView 可能无法响应 viewDidAppear:(BOOL)animated... 这可能是它不起作用的原因吗?
    • 抱歉,我的意思是执行相同的一般步骤。 viewDidAppear: 是一种方便的方法,用于获取第一响应者状态如果您是UIViewController。如果您必须为此使用UIView,您将需要在其他地方调用becomeFirstResponder。您可以随时使用isFirstResponder查看特定的 UI 元素是否是第一响应者。
    【解决方案2】:

    你有没有实现旧方法

    '加速计:didAccelerate'

    ?如果您实现了旧的应用程序范围的方法,则需要在调用新方法之前将其删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-18
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多