Hat jemand eine Funktion implementiert, bei der Sie eine bestimmte Aktion ausführen, wenn der Benutzer den Bildschirm für einen bestimmten Zeitraum nicht berührt hat? Ich versuche herauszufinden, wie ich das am besten machen kann.
In UIApplication gibt es diese etwas verwandte Methode:
[UIApplication sharedApplication].idleTimerDisabled;
Es wäre schön, wenn Sie stattdessen so etwas hätten:
NSTimeInterval timeElapsed = [UIApplication sharedApplication].idleTimeElapsed;
Dann könnte ich einen Timer einrichten und diesen Wert regelmäßig überprüfen und Maßnahmen ergreifen, wenn er einen Schwellenwert überschreitet.
Hoffentlich erklärt das, wonach ich suche. Hat sich bereits jemand mit diesem Problem befasst oder haben Sie sich Gedanken darüber gemacht, wie Sie es tun würden? Vielen Dank.
ios
objective-c
iphone
idle-timer
Mike McMaster
quelle
quelle
Antworten:
Hier ist die Antwort, nach der ich gesucht hatte:
Lassen Sie Ihre Anwendung die Unterklasse UIApplication delegieren. Überschreiben Sie in der Implementierungsdatei die sendEvent: -Methode wie folgt:
Dabei sind maxIdleTime und idleTimer Instanzvariablen.
Damit dies funktioniert, müssen Sie auch Ihre main.m ändern, um UIApplicationMain anzuweisen, Ihre Delegatenklasse (in diesem Beispiel AppDelegate) als Hauptklasse zu verwenden:
quelle
NSTimer
Instanzen, wenn es viele Berührungen gibt.Ich habe eine Variante der Idle-Timer-Lösung, für die keine UIA-Anwendung der Unterklasse erforderlich ist. Es funktioniert in einer bestimmten UIViewController-Unterklasse und ist daher nützlich, wenn Sie nur einen View-Controller haben (wie eine interaktive App oder ein Spiel) oder nur das Leerlaufzeitlimit in einem bestimmten View-Controller verarbeiten möchten.
Außerdem wird das NSTimer-Objekt nicht jedes Mal neu erstellt, wenn der Leerlauf-Timer zurückgesetzt wird. Es wird nur dann ein neuer erstellt, wenn der Timer ausgelöst wird.
Ihr Code kann
resetIdleTimer
alle anderen Ereignisse aufrufen , die möglicherweise den Leerlauf-Timer ungültig machen müssen (z. B. die Eingabe eines signifikanten Beschleunigungsmessers).(Speicherbereinigungscode aus Gründen der Kürze ausgeschlossen.)
quelle
Für schnelle v 3.1
Vergessen Sie nicht, diese Zeile in AppDelegate // @ UIApplicationMain zu kommentieren
Benachrichtigung in einer anderen Klasse beobachten
quelle
if idleTimer != nil
in-sendEvent()
Methode benötigen ?timeoutInSeconds
Antwort des Webdienstes festlegen ?Dieser Thread war eine große Hilfe, und ich habe ihn in eine UIWindow-Unterklasse eingepackt, die Benachrichtigungen sendet. Ich habe Benachrichtigungen ausgewählt, um eine echte lose Kopplung zu erzielen, aber Sie können problemlos einen Delegaten hinzufügen.
Hier ist das Wesentliche:
http://gist.github.com/365998
Der Grund für das Problem mit der UIApplication-Unterklasse besteht darin, dass die NIB so eingerichtet ist, dass dann zwei UIApplication-Objekte erstellt werden, da sie die Anwendung und den Delegaten enthält. Die UIWindow-Unterklasse funktioniert jedoch hervorragend.
quelle
Eigentlich funktioniert die Idee der Unterklasse großartig. Machen Sie Ihren Delegierten nur nicht zur
UIApplication
Unterklasse. Erstellen Sie eine andere Datei, die vonUIApplication
(z. B. myApp) erbt . Setzen Sie in IB die Klasse desfileOwner
Objekts aufmyApp
und implementieren Sie in myApp.m diesendEvent
Methode wie oben. In main.m tun:et voilà!
quelle
Ich bin gerade auf dieses Problem mit einem Spiel gestoßen, das durch Bewegungen gesteuert wird, dh die Bildschirmsperre ist deaktiviert, sollte es aber im Menümodus wieder aktivieren. Anstelle eines Timers habe ich alle Aufrufe
setIdleTimerDisabled
innerhalb einer kleinen Klasse mit den folgenden Methoden gekapselt :disableIdleTimer
Deaktiviert den Leerlauf-Timer,enableIdleTimerDelayed
wenn Sie das MenüenableIdleTimer
aufrufen oder was auch immer mit aktivem Leerlauf-Timer ausgeführt werden soll, und wird von der AppDelegate-applicationWillResignActive
Methode aufgerufen, um sicherzustellen, dass alle Ihre Änderungen ordnungsgemäß auf das Standardverhalten des Systems zurückgesetzt werden.Ich habe einen Artikel geschrieben und den Code für die Singleton-Klasse IdleTimerManager Idle Timer Handling in iPhone-Spielen bereitgestellt
quelle
Hier ist eine andere Möglichkeit, Aktivität zu erkennen:
Der Timer wird hinzugefügt
UITrackingRunLoopMode
, sodass er nur beiUITracking
Aktivität ausgelöst werden kann. Es hat auch den schönen Vorteil, dass Sie nicht für alle Berührungsereignisse gespammt werden, um zu informieren, ob in den letztenACTIVITY_DETECT_TIMER_RESOLUTION
Sekunden Aktivität stattgefunden hat. Ich habe den Selektor benannt,keepAlive
da dies ein angemessener Anwendungsfall ist. Sie können natürlich mit den Informationen, dass in letzter Zeit Aktivitäten stattgefunden haben, tun, was Sie wollen.quelle
Letztendlich müssen Sie definieren, was Sie als inaktiv betrachten. Ist inaktiv das Ergebnis, dass der Benutzer den Bildschirm nicht berührt, oder ist es der Status des Systems, wenn keine Computerressourcen verwendet werden? In vielen Anwendungen ist es möglich, dass der Benutzer etwas tut, auch wenn er nicht aktiv über den Touchscreen mit dem Gerät interagiert. Während der Benutzer wahrscheinlich mit dem Konzept des Ruhezustands des Geräts und dem Hinweis, dass dies durch Dimmen des Bildschirms geschieht, vertraut ist, ist es nicht unbedingt so, dass er erwartet, dass im Leerlauf etwas passiert - Sie müssen vorsichtig sein darüber, was du tun würdest. Zurück zur ursprünglichen Aussage: Wenn Sie den ersten Fall als Ihre Definition betrachten, gibt es keinen wirklich einfachen Weg, dies zu tun. Sie müssten jedes Berührungsereignis erhalten, Weitergabe an die Antwortkette nach Bedarf unter Angabe der Empfangszeit. Dies gibt Ihnen eine Grundlage für die Berechnung des Leerlaufs. Wenn Sie den zweiten Fall als Ihre Definition betrachten, können Sie mit einer NSPostWhenIdle-Benachrichtigung spielen, um zu versuchen, Ihre Logik zu diesem Zeitpunkt auszuführen.
quelle
Es gibt eine Möglichkeit, diese App breit zu machen, ohne dass einzelne Controller etwas tun müssen. Fügen Sie einfach eine Gestenerkennung hinzu, die Berührungen nicht abbricht. Auf diese Weise werden alle Berührungen für den Timer verfolgt, und andere Berührungen und Gesten werden überhaupt nicht beeinflusst, sodass niemand anderes davon wissen muss.
Wenn die Startmethode Ihres App-Delegaten abgeschlossen ist, rufen Sie einfach addGesture auf und schon sind Sie fertig. Alle Berührungen durchlaufen die Methoden von CatchAllGesture, ohne dass die Funktionalität anderer beeinträchtigt wird.
quelle
-sendEvent:
ist übertrieben und behandeltUITrackingRunLoopMode
nicht viele Fälle.