Прослушайте все сенсорные события в приложении для iOS - PullRequest
20 голосов
/ 09 декабря 2011

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

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

Ответы [ 6 ]

33 голосов
/ 09 декабря 2011

Это действительно легко.

Вам нужен подкласс 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];
}

4 голосов
/ 09 декабря 2011

Для этого можно использовать подкласс 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 голосов
/ 25 февраля 2016

Создайте класс «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
{


}
2 голосов
/ 13 февраля 2015

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

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

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

1 голос
/ 09 декабря 2011

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

0 голосов
/ 30 мая 2019

В Swift 4.2 1. Создайте подкласс объекта UIApplication и напечатайте действие пользователя:

    import UIKit
    class ANUIApplication: UIApplication {

        override func sendAction(_ action: Selector, to target: Any?, from sender: Any?, for event: UIEvent?) -> Bool {
            print("FILE= \(NSStringFromSelector(action)) METHOD=\(String(describing: target!)) SENDER=\(String(describing: sender))")
            return super.sendAction(action, to: target, from: sender, for: event)
        }   
    }
В файле AppDelegate.swift вы найдете точку входа приложения @UIApplicationMain. Добавьте комментарий и добавьте новый файл swift main.swift и добавьте следующий код в файл main.swift

import UIKit

UIApplicationMain (CommandLine.argc, CommandLine.unsafeArgv, NSStringFromClass (ANUIApplication.self), NSStringFromClass (AppDelegate.self))

ANUIApplication добавлен в класс, где мы добавили классжурналы действий.AppDelegate является делегатом приложения по умолчанию, в котором мы писали методы делегата приложения (полезно для отслеживания действий и имени файла в большом проекте)

...