I noticed that whenever the Control Center is being used on the iPhone, glkView:drawInRect: of my underlying app is not being called - hence the animation appears frozen. This happens as soon as the interaction with the Control Center starts - even when majority of the app is still visible. Animations that are not OpenGL based continue running just fine.
Is there any way to make the app call this method despite the Control Center showing, or is this an inherent limitation of OpenGL?
Related
Implementing a sort of 'distress call' button which should work as following:
User starts application and covers a screen with a palm of a hand
Some time passes, user may introduce additional touches during that time or remove some of the existing (but not all of them), location/shape of touches may change
When user releases a hand (i.e. removes last touch) a distress signal is emitted by the app
Basically, the app should register two events: (1) a screen is touched (2) all touched are released
I'm trying to use touchesBegan/touchesEnded methods and those work for small area touches (fingertips) but on touching screen with a full palm or even only palm edge a touchesCancelled gets triggered immediately while hand is still on the screen. Obviously no other events are emitted upon hand release afterwards.
I tried subclassing UIWindow and UIApplication and overriding sendEvent in those but got no additional info - large area touches are triggering touch begin and immediately touch cancel, releasing hand afterwards emits nothing. In some cases large area touches fire no events at all, not even the touchesBegan. Basically, iOS doesn't let me work with a very basic scenario - detecting just the fact of screen touch/release.
Is there any way to query the screen touch state directly and not work with responder chain? Or suppress the cancellation event from firing? Or maybe I'm missing something?
Unfortunately, as of right now, no solution exists
My app can be launched via UIApplicationLaunchOptionsLocalNotificationKey in the background. In that case the usual flow to setup initail view controller and some animations on the app's landing-page/first-page of the app take place.
My question is, Is this a good practice, If I leave these animations like this even when my app is launched via OS in background? Three things I am concerned about:
Some animations are continuous, like a circular-dot(UIImage) expanding and shrinking, using CAAnimation.
Some views are added and removed as subviews to the keyWindow, based on user location.
When user taps the home button, do I need to stop the animations and subview additions then also?
Making the animation stop and resume via applicationDidEnterBackground and applicationWillEnterForeground seems tedious.
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.
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.
Doing some investigation online, I've noticed that gpus_ReturnNotPermittedKillClient gets thrown when OpenGL actions are triggered while an app is backgrounded. I'm currently working on a project that involves a map view and an overlay (using Apple's Breadcrumb sample code). These actions are performed on the main thread, but there's a possibility that the app could get backgrounded as the map view becomes initialized or the view gets pushed onto the screen.
I also use location services to retrieve points through GPS, but I don't update the overlay unless we're in the foreground.
Is it to my understanding that since iOS 6, MKMapView's are now created with OpenGL? If this is the case, then could drawing the overlay also be through OpenGL? This could help explain why I've been getting this error randomly.
I've heard of some ways to cancel all OpenGL actions, such as invoking glFinish() in applicationDidEnterBackground and applicationWillResignActive or using [[CCDirector sharedDirector] pause]. Considering this, what would be the best solution to eliminate any OpenGL drawing with an MKMapView/MKOverlayView?
After trying multiple solutions, I realized that the thing that was causing this crash was an adjustment of the map view's frame that was being fired off a few seconds after the map was allocated. A status bar is dropped down, and the map's frame was animated downward by a few pixels. Because of this, the map (supposedly) had to be re-drawn, causing a crash if this animation was occurring in the background.
I now keep track of the state of the status bar in relation to the app's active status, and only animate if the application state is UIApplicationStateActive. Having done this, I haven't had a crash since.