iOS notified when control center is opened like QuizUp do - ios

How can I be notified when the iOS Control Center is being opened?
UIApplicationWillResignActiveNotification isn't good enough since this notification is sent also when the Notifications Center is opened, alert view appeared and other possible scenarios.
I was sure this is not possible, but QuizUp app is notified when the user open the Control Center while the user is on middle of a gameplay to prevent cheating the game.
Thanks

Hey there I did a lot of trial and error investigation and came up with a solution that turns out being very reliable. It works in all orientations and both in fullscreen (no statusbar) and in regular mode. AAWindow is a subclass of UIWindow and you can find it on GitHub.
The way I accomplished this is by overriding sendEvent in UIWindow, separating out TouchEvents from the other events and checking whether touches occur in the bottom 10 percent of the screen (which is the part that can open Control Center). If there are touches and applicationWillResignActive is called within a timespan of .5 seconds (with statusbar) or 3 seconds (without statusbar) you can be very sure that this is because of Control Center being opened. Then a NSNotification is being fired and you can react to that anywhere in the application.

I tested a UIPanGestureRecognizer approach (with and without the status bar visible—changes if the little pull tab comes up instead of control center) along with watching for the applicationWillResignActive notification, and I couldn't reliably know if control center was opened. If the pan was slow enough the gesture recognizer would trigger first, but it's definitely easy to swipe up fast enough to trigger control center and bypass the gesture recognizer firing at all.
Attempting to check if the app goes from applicationWillResignActive and then to applicationDidBecomeActive would be a pretty reliable way to know if the app entered and exited one of a couple states (control center, notification center, answering a phone call, etc), but telling the difference between say notification and control center is impossible this way.
TL;DR: I don't think there is a reliable or accurate way to tell if control center was opened, but QuizUp may be doing something interesting to fake it, and I am open to being wrong!

When Control centre is opened the cycle isn't completed. Means only the method
applicationDidResignActivity will be called but applicationDidEnterBackground won't be called. When app is minimized both methods will be called. Here you can differentiate.

Related

want to catch a window change event in iOS

I want to detect when any notification of any app comes in.
I was looking for a sort of "window will open" event, to detect when the notification window pops up, but as far as I can see there is no such thing.
Would it be possible to use the "viewWillStartLiveResize" in some way or another for this purpose ?
Or is there any other way to detect a screen change event?
viewWillTransitionToSize:withTransitionCoordinator: or traitCollectionDidChange: should be enough to detect app screen size change (especially on an ipad split mode). But in your case that's not possible - you have an access to your and only your app views hierarchy. Push notification windows pops up over your app on a springboard view hierarchy. So as notification center, etc. They just don't resize your app's window, they overlap it.

How can I detect from iOS Keyboard extension if user scrolled up the Control Center?

I develop an iOS Keyboard extension, and I'm using scroll gestures on keyboard. Sometimes when using the keyboard I scroll up the control center and my keyboard stops working fine. Is there any way to detect if control center become visible, or invisible?
You can't do it directly. The most you can know is that your app was deactivated and then activated again. It could be because of the control center, it could be because of the notification center, it could be because a phone call came in, it could be because the user went into the app switcher and came back again...
Here is the possible work around you can try:
It is the UIWindow subclass to enable behavior like adaptive round-corners & detecting when Control Center is opened. This UIWindow subclass does probably the thing you want. You simply subscribe to an NSNotification and can react to the user opening Control Center. Detailed instructions and setup on Github
https://github.com/aaronabentheuer/AAWindow
[AAWindow: The way this is accomplished is by using a combination of NSTimer and overwriting sendEvent in UIWindow to receive all touches without blocking them. So you basically receive all touches check if they are near the lower edge of the screen, if yes set a timer for a half a second and if during this timer is running applicationWillResignActive is called you can be almost certain that ControlCenter is opened. The time has to vary if there's no statusbar, because then the app is in fullscreen and it can take the user up to 3 seconds to launch Control Center.]
Hope it would help you figure out the exact solution to your problem.

iOS Swift Briefly Display Info

I want to have some information drop down from the top of a view, stay on the screen for a second or two, and then go back up out of the view. I have search for displaying notifications and/or banners. All I get is either push notifications (which I don't need to use) or iAds banners.
I'm working on a barcode scanning app and I want to briefly show the value of the barcode shown without requiring the user to tap on anything. How can I accomplish this?
Don't use notifications and banners, because that might not work: the user can turn them off. In any case this is not a notification of anything, so it's a misuse of notifications.
Just do what you described, yourself: animate a view onto the screen, and then (in the animation's completion handler) use delayed performance to animate the view right back off the screen after a short delay.
You should use a view which manages its own state (INCOMING, STAY PUT, OUTGOING). This way you can reduce the memory footprint and many other bugs in the process. I coded something for a similar process. Check it out

Getting touches at launch on iOS

On Mac, one can always get the location of the mouse "outside the event stream" (ie, even if you've not subscribed to any delegate methods for mouseUp: et al) by calling [NSEvent mouseLocation].
Is there any way on iOS to get current touch events without listening to touchesBegan:?
I ask because there is at least one situation in which touchesBegan is not called: at app launch, if a touch is already in progress, touchesBegan is never called. In fact, neither are any of the touch-related UIEvent methods called as near as I can tell (nor UIApplication's / UIWindow's sendEvent:, apparently).
I would like to vary the behavior of my app slightly based on whether a touch is in progress at launch. Is there any way to detect an in-progress touch at app launch?
This cannot be done. The simple reason: The touch events don't belong to your app. Each touch belongs to some UI element (or responder). As you already know, this element gets the began, moved, ended, cancelled messages.
This is even true within a properly programmed app: All events regarding one touch are delivered to the very same object. After all, how would another object know what to do with that event, and how should the first object properly finish its expected behavior?
While you can (or could, but probably shouldn't) find a work around within your app, there's just no way for cross-app-touch passings.
And on the Mac you may query the mouse position, but in normal application flow there'll always be a mouse down before you get a mouse up event.
To be honest, I don't see any reason why this would be needed anyway... oh wait... I could split my app icon into several areas... not sure if it would already break privacy laws, though, if you get to know where the user has his icon on screen.
I think you could simply "extend" the application launch. When I had time consuming tasks during my application launch, I used to show the same splash screen with a UIActivityIndicator while the action was being carried out.
You could simply create a NSTimer, wait for about 2 seconds and during this time, check for touches, while the splash screen will still be showing.
To do this, in applicationDidFinishLaunch, push a ViewController that looks exactaly like the splash screen and check for touches in this ViewController. After those 2 seconds, proceed with normal initialisation. This behaviour also helps if you have time consuming tasks during initialisation.
I know, it`s a workaround, but my guess, is that it is not possible to check for touches because application will be working on the main thread and the touches also processes on the main thread. This could happen also because there are no ViewControllers or UIWindow initialised and ready to listen to touches.
Hope it helps.
You might try handling the hitTest:withEvent: instead.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
Since according to apple doc "Returns the farthest descendant of the receiver in the view hierarchy (including itself) that contains a specified point."

UILocalNotifcation custom fire event, or struggle on with NSTimer

I have a state-transition problem with NSTimer, of which I find difficult to keep track of during applicationWillResignActive / applicationDidEnterBackground, according to the context of my app.
I was wondering if it might not be a better idea to utilise UILocalNotification, especially given it's background/inactive firing. However, I wanted to know whether we have the ability to provide a custom method to UILocalNotification, of which does not present a dialog box (would damage the whole point of my app). In effect, i'd like to only make use of the timer-fire capabilities of UILocalNotification, and handle the fire event with my own method which does something very "undialog-friendly"
Have checked the ADC docs and it alludes to the dialog being presented every time.
Any advice you can give on this would be appreciated.
thanks
sc.
The dialog box is presented when your app is in the background. But it is not presented when your app is running - instead your app is free to deal with the notification however it sees fit. So it would be perfectly possible to hook it up to a custom method of your own making.
The main reason for this behaviour is a user may not want to go into your app if it's in the background. Of course, with iOS 5 the notification may not be a dialog box - it could be one of the new notification styles.

Resources