Czy ktoś zaimplementował funkcję, w której jeśli użytkownik nie dotyka ekranu przez określony czas, wykonujesz określoną czynność? Próbuję znaleźć najlepszy sposób na zrobienie tego.
W UIApplication jest ta nieco powiązana metoda:
[UIApplication sharedApplication].idleTimerDisabled;
Byłoby miło, gdybyś zamiast tego miał coś takiego:
NSTimeInterval timeElapsed = [UIApplication sharedApplication].idleTimeElapsed;
Następnie mógłbym ustawić licznik czasu i okresowo sprawdzać tę wartość i podejmować działania, gdy przekroczy próg.
Mam nadzieję, że to wyjaśnia, czego szukam. Czy ktoś już zajął się tym problemem lub ma jakieś przemyślenia, jak byś to zrobił? Dzięki.
ios
objective-c
iphone
idle-timer
Mike McMaster
źródło
źródło
Odpowiedzi:
Oto odpowiedź, której szukałem:
Miej podklasę delegata aplikacji UIApplication. W pliku implementacji nadpisz metodę sendEvent: w następujący sposób:
gdzie maxIdleTime i idleTimer są zmiennymi instancji.
Aby to zadziałało, musisz również zmodyfikować plik main.m tak, aby UIApplicationMain używał Twojej klasy delegata (w tym przykładzie AppDelegate) jako klasy głównej:
źródło
NSTimer
przypadków, jeśli jest dużo akcentów.Mam odmianę rozwiązania licznika czasu bezczynności, która nie wymaga podklasy UIApplication. Działa na określonej podklasie UIViewController, więc jest przydatny, jeśli masz tylko jeden kontroler widoku (taki jak interaktywna aplikacja lub gra) lub chcesz tylko obsłużyć limit czasu bezczynności w określonym kontrolerze widoku.
Nie odtwarza również obiektu NSTimer za każdym razem, gdy licznik czasu bezczynności jest resetowany. Tworzy nowy tylko wtedy, gdy timer odpala.
Twój kod może wywoływać
resetIdleTimer
inne zdarzenia, które mogą wymagać unieważnienia licznika czasu bezczynności (takie jak znaczące wejście akcelerometru).(kod czyszczenia pamięci został wykluczony ze względu na zwięzłość).
źródło
Dla Swift v 3.1
nie zapomnij skomentować tej linii w AppDelegate // @ UIApplicationMain
Obserwowanie powiadomień w dowolnej innej klasie
źródło
if idleTimer != nil
wsendEvent()
metodzie?timeoutInSeconds
z odpowiedzi usługi internetowej?Ten wątek był bardzo pomocny i zawarłem go w podklasę UIWindow, która wysyła powiadomienia. Wybrałem powiadomienia, aby było to naprawdę luźne powiązanie, ale możesz łatwo dodać delegata.
Oto sedno:
http://gist.github.com/365998
Ponadto przyczyną problemu z podklasą UIApplication jest to, że NIB jest skonfigurowany do tworzenia 2 obiektów UIApplication, ponieważ zawiera aplikację i delegata. Podklasa UIWindow działa jednak świetnie.
źródło
Właściwie pomysł na podklasy działa świetnie. Po prostu nie ustawiaj delegata w
UIApplication
podklasie. Utwórz inny plik, który dziedziczy poUIApplication
(np. MyApp). W IB ustaw klasęfileOwner
obiektu na,myApp
aw myApp. M zaimplementujsendEvent
metodę jak powyżej. W main.m do:zrobione!
źródło
Właśnie napotkałem ten problem z grą, która jest kontrolowana przez ruchy, tj. Ma wyłączoną blokadę ekranu, ale powinna włączyć ją ponownie w trybie menu. Zamiast timera zawarłem wszystkie wywołania
setIdleTimerDisabled
w małej klasie, zapewniając następujące metody:disableIdleTimer
dezaktywuje licznik czasu bezczynności,enableIdleTimerDelayed
gdy wchodzisz do menu lub cokolwiek powinno działać z aktywnym licznikiem czasu bezczynności ienableIdleTimer
jest wywoływane zapplicationWillResignActive
metody AppDelegate, aby zapewnić, że wszystkie zmiany zostaną poprawnie zresetowane do domyślnego zachowania systemu.Napisałem artykuł i podałem kod pojedynczej klasy IdleTimerManager Idle Timer Handling w grach na iPhone'a
źródło
Oto inny sposób wykrywania aktywności:
Timer jest dodawany
UITrackingRunLoopMode
, więc może działać tylko wtedy, gdy jestUITracking
aktywność. Ma również tę zaletę, że nie spamuje Cię w przypadku wszystkich zdarzeń dotykowych, informując w ten sposób, czy w ciągu ostatnichACTIVITY_DETECT_TIMER_RESOLUTION
sekund była aktywność . Nazwałam selektor,keepAlive
ponieważ wydaje się to odpowiednim przypadkiem użycia. Możesz oczywiście robić, co chcesz, z informacją, że ostatnio miała miejsce aktywność.źródło
Ostatecznie musisz zdefiniować, co uważasz za bezczynne - czy bezczynność wynika z tego, że użytkownik nie dotyka ekranu, czy też jest to stan systemu, jeśli nie są używane żadne zasoby obliczeniowe? W wielu aplikacjach użytkownik może coś robić, nawet jeśli nie wchodzi w aktywną interakcję z urządzeniem za pośrednictwem ekranu dotykowego. Chociaż użytkownik prawdopodobnie jest zaznajomiony z koncepcją zasypiania urządzenia i zauważa, że stanie się to poprzez przyciemnianie ekranu, niekoniecznie jest tak, że spodziewa się, że coś się stanie, jeśli będzie bezczynny - trzeba być ostrożnym o tym, co byś zrobił. Ale wracając do pierwotnego stwierdzenia - jeśli uznasz pierwszy przypadek za swoją definicję, nie ma naprawdę łatwego sposobu, aby to zrobić. Musisz otrzymywać każde zdarzenie dotykowe, przekazywanie go w razie potrzeby w łańcuchu odpowiedzi, jednocześnie odnotowując czas jego otrzymania. To da ci podstawę do wykonania bezczynnych obliczeń. Jeśli uważasz, że drugi przypadek jest twoją definicją, możesz grać z powiadomieniem NSPostWhenIdle, aby spróbować wykonać swoją logikę w tym czasie.
źródło
Jest sposób na zrobienie tej aplikacji bez konieczności wykonywania jakichkolwiek czynności przez poszczególne kontrolery. Po prostu dodaj rozpoznawanie gestów, który nie anuluje dotknięć. W ten sposób wszystkie dotknięcia będą śledzone dla timera, a inne dotknięcia i gesty w ogóle nie będą miały wpływu, więc nikt inny nie musi o tym wiedzieć.
W przypadku, gdy delegat aplikacji zakończył metodę uruchamiania, po prostu wywołaj addGesture i gotowe. Wszystkie dotknięcia przechodzą przez metody CatchAllGesture bez przeszkadzania w działaniu innych.
źródło
-sendEvent:
jest przesadą iUITrackingRunLoopMode
nie obsługuje wielu przypadków.