Подтвердить что ты не робот

Слушайте все события касания в приложении iOS

Можно ли каким-то образом слушать и улавливать все события касания, происходящие в приложении?

Приложение, которое я сейчас разрабатываю, будет использоваться в демонстрационных залах и информационных киосках, и поэтому я хотел бы вернуться в стартовую часть приложения, если никаких касаний не было получено за пару минут. Это своего рода заставка, если хотите. Я планирую реализовать это, используя таймер, работающий в фоновом режиме, который должен быть reset и перезапускается каждый раз, когда событие касания происходит где-то в приложении. Но как я могу слушать события касания? Любые идеи или предложения?

4b9b3361

Ответ 1

Это очень просто.

Вам нужен подкласс UIApplication (позвоните ему MyApplication).

Вы изменяете свой main.m, чтобы использовать его:


return UIApplicationMain(argc, argv, @"MyApplication", @"MyApplicationDelegate");

И вы переопределите метод [MyApplication sendEvent:]:


- (void)sendEvent:(UIEvent*)event {
    //handle the event (you will probably just reset a timer)

    [super sendEvent:event];
}

Ответ 2

Для этого можно использовать подкласс UIWindow, переопределяя hitTest:. Затем в XIB вашего главного окна есть объект, обычно называемый просто Window. Нажмите это, затем справа на панели "Утилиты" перейдите в "Тождества" (Alt-Command-3). В текстовом поле Class введите имя своего подкласса UIWindow.

MyWindow.h

@interface MyWindow : UIWindow
@end

MyWindow.m

@implementation MyWindow

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *res;

    res = [super hitTest:point withEvent:event];

    // Setup/reset your timer or whatever your want to do.
    // This method will be called for every touch down,
    // but not for subsequent events like swiping/dragging.
    // Still, might be good enough if you want to measure
    // in minutes.

    return res;
}   

@end

Ответ 3

Для этого вы можете использовать распознаватель жестов. Подкласс UITapGestureRecognizer и импортировать <UIKit/UIGestureRecognizerSubclass.h>. Это определяет touchesBegan:, touchesMoved:, touchesEnded: и touchesCancelled:. Поместите свой код обработки касания соответствующими методами.

Произведите активацию распознавателя жестов в application:didFinishLaunchingWithOptions: и добавьте его в UIWindow. Установите cancelsTouchesInView в NO, и он пройдет все касания прозрачным образом.

Кредит: этот пост.

Ответ 4

Создайте класс "VApplication", который простирается от UIApplication  и вставьте этот код в соответствующий класс

VApplication.h

#import <Foundation/Foundation.h>

// # of minutes before application times out
#define kApplicationTimeoutInMinutes 10

// Notification that gets sent when the timeout occurs
#define kApplicationDidTimeoutNotification @"ApplicationDidTimeout"

/**
 * This is a subclass of UIApplication with the sendEvent: method 
 * overridden in order to catch all touch events.
 */

@interface VApplication : UIApplication
{
    NSTimer *_idleTimer;
}

/**
 * Resets the idle timer to its initial state. This method gets called
 * every time there is a touch on the screen.  It should also be called
 * when the user correctly enters their pin to access the application.
 */
- (void)resetIdleTimer;

@end

VApplication.m

#import "VApplication.h"
#import "AppDelegate.h"

@implementation VApplication

- (void)sendEvent:(UIEvent *)event
{
    [super sendEvent:event];
    // Fire up the timer upon first event
    if(!_idleTimer) {
        [self resetIdleTimer];
    }

    // Check to see if there was a touch event
    NSSet *allTouches       = [event allTouches];

    if  ([allTouches count] > 0)
        {
        UITouchPhase phase  = ((UITouch *)[allTouches anyObject]).phase;
        if  (phase == UITouchPhaseBegan)
            {
            [self resetIdleTimer];         
            }
        }
}

- (void)resetIdleTimer 
{
    if  (_idleTimer)
        {
        [_idleTimer invalidate];
        }

    // Schedule a timer to fire in kApplicationTimeoutInMinutes * 60


//  int timeout =   [AppDelegate getInstance].m_iInactivityTime;
    int timeout =   3;
    _idleTimer = [NSTimer scheduledTimerWithTimeInterval:timeout
                                                  target:self 
                                                selector:@selector(idleTimerExceeded) 
                                                userInfo:nil 
                                                 repeats:NO];

}

- (void)idleTimerExceeded
{
    /* Post a notification so anyone who subscribes to it can be notified when
     * the application times out */


    [[NSNotificationCenter defaultCenter]
     postNotificationName:kApplicationDidTimeoutNotification object:nil];
}


@end

Замените имя класса "VApplication" на наш

main.m

файл, подобный этому

int main(int argc, char * argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, @"VApplication", NSStringFromClass([AppDelegate class]));

    }
}

Зарегистрировать уведомление для вашего соответствующего контроллера представления

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidTimeout:) name:kApplicationDidTimeoutNotification object:nil];

И как только истечет время ожидания, уведомление будет запускать и обрабатывать событие, подобное этому

- (void) applicationDidTimeout:(NSNotification *) notif //inactivity lead to any progress
{


}

Ответ 5

Вы можете поместить прозрачный вид в верхней части иерархии представлений и выбрать в этом представлении, обрабатывать ли события касания, которые он получает, или передавать их для более низких просмотров.