motionBegan: не работает - PullRequest
       35

motionBegan: не работает

12 голосов
/ 27 августа 2009

У меня возникает небольшая проблема, когда я пытаюсь использовать (void) motionBegan: (UIEventSubtype) motion withEvent: (UIEvent *) для захвата события встряхивания. Проблема в том, что функция даже не работает, даже когда я перезаписываю 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»

Ответы [ 2 ]

31 голосов
/ 28 августа 2009

Я предполагаю, что вы хотите реализовать это в подклассе 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];
    }
}

На форуме разработчиков iPhone есть хорошее сообщение от Мэтта Дранса из Apple (требуется регистрация в качестве разработчика).

Обновление: реализация в подклассе UIView

Как обсуждалось в комментариях, это также работает, что не удивительно, в подклассе 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. Поразитесь сообщению журнала.

0 голосов
/ 27 августа 2009

У вас реализован старый метод? Если у вас реализован старый метод для всего приложения, вам нужно удалить его, прежде чем будет вызван новый.

...