Gesture response slows with use - ios

I am using UIGestureRecognizer to detect taps or swipes and change page in my app.
After some use (perhaps 50 odd page loads) the app starts to respond noticeably slower to gestures. You can tap and wait a full second for the gesture to be recognised.
I have checked my code and it is not the page turning that is slowing down, as that still works by other means (bluetooth keyboard). Also the response of buttons and menus does not slow down.
Does anyone know what might be causing this? It eventually causes the app to become unusable.

There could be quite a few things. The first thing I would do is run instruments against the app and look for leaks. A slow down like this could be caused by objects being created and not released. Also note that the leaks instrument does not pick up everything. I've often picked up on objects leaking by looking at the allocations and checking that the correct number of instances are alive.

Problem solved! It turns out I was adding new gesture recognisers each time a page was loaded without removing the previous ones.

I was having this slow segue problem, only when swiping for the segue. I came to this thread and saw the post from #colincameron saying that he was stacking gesture recognizers with each load.
So I went and found this SO thread, where #robmayoff shows how to remove all gesture recognizers from a view. You could add this removal code to your prepareForSegue, viewDidDisappear, etc
Swift
subview.gestureRecognizers?.forEach(subview.removeGestureRecognizer)
That code solved my slow segue problem.

Related

All UIView animation / transitions becoming non-animated after a while?

I have a strange issue both on mobile device and in simulator.
After a while spent in the application, animations on UIView are disabled (like if animated was set to NO), notably on :
pushViewController in a UINavigationController (also true for popTo)
displaying a UIActionSheet
switching between views with IIDeckViewController
This is quite strange as all transition are usually animated, and in a non predictable way, they all become non-animated
Everything was working well a few days agos, and as far as I can remind, I did not make any changes that should lead to such a behavior.
Any ideas ?
Thanks
Cheers
We recently had some trouble like this, the culprit was initiating some animations from a non-main thread (perhaps you are initiating a transition). This caused some trouble with animations transactions getting rolled back and this broke animations until the transaction was rolled back. There were some entries on the console pointing to CA transactions. Setting CA_DEBUG_TRANSACTIONS=1 on the environment quickly revealed the stack of where the the transactions were started.
The fix was to not do anything that would create transactions from a non-main thread.

Is it possible to increase keyboard first launch performance in iOS

There is always a delay (2-3seconds) on the first time the keyboard got invoked in application. Is there a method or a trick to improve this experience? I tried to use NSTreading, but it crashes on error "only perform on Main Thread" if I use [textfield becomeFirstResponder]; Any ideas?
As a general rule, do not try to touch UI elements from a background thread unless the documentation specifically states that it is thread-safe.
In your case, attempting to preload the keyboard in the background will not work. Keep in mind that the keyboard isn't created just within your application — it's shared across the system. That means if the system decides it needs to clear up some memory it will most likely "uncache" the keyboard if it's not visible.
If this is occurring in the Simulator, that's most likely because you're quitting the Simulator after every test run. As a result, the keyboard has to be loaded each time you run a test. If this is happening on a device, however, then most likely your device is frequently running low on memory.
That being said, if the instant showing is incredibly important, you could always try to use the old trick of making an invisible UITextField first responder, then immediately resigning first responder in order to force the keyboard to load.
maybe try a different keyboard? or try going into setting and looking at the input options, and go to keyboard. most of the time its because the programming is lagging, or you have more programms running in the background

iOS crash - no leaks, NSZombie enabled and doesn't breaking on exceptions

I am writing an iPad app which uses an AVPlayer to display a video. There's buttons to jump to various parts of the video, and when the user rotates the device, I change the size of the view which holds the AVPlayer layer.
My problem is that after a certain amount of device orientation changes and jumps around the video, the app crashes.
I have NSZombie enabled - this doesn't break.
I have a breakpoint enabled in my code to catch exceptions - this doesn't break.
I have run instruments and the code isn't leaking.
Allocations simply shows the "Overall Bytes" growing and growing with every action until it hits 14 meg and the pad crashes.
I feel like I have no way of getting to the bottom of this. Am I missing some trick to solving this? Does AVPlayer need some special treatment when being released?
ANY HELP, MUCH APPRECIATED.
Use instruments to check your Allocations. I recently had a very similar problem where there were no memory leaks but my Overall Bytes kept growing every time I launched a particular ViewController (and it would eventually crash).
It turned out that the ViewController itself was a strong reference as a delegate to another class (oops) and each time I dismissed the ViewController that other class still had a reference to it. Therefore each time I launched and dismissed this ViewController I would create another instance of it that would never die (and never leak).
Your exact problem may be different but you should be able to see the reason for your Overall Bytes growing by checking out your Allocations.

iOS screen is constantly refreshed using UIAccessibility voiceover

I have an iOS app and I want to make it accessible. Everything goes well but in some screens the voice over loses it's focus and jumps to the first accessible element. It's like the screen is always refreshing. I have used UIAccessibilityInspector and I observed that there are ScreenChanged notifications constantly, from time to time. It's really annoying because I don't know why are those notifications sent and how do I stop/control them.
Thanks,
Alex
I had a similar problem and found that it was caused by a UIPageControl and a timer that I set up to automatically cycle the pages in that control. For some reason, the scrolling caused by that was resetting UIAccessibility to the first element in the view, just like you said. Check and see if you have anything animating or changing state.

Why are my iPad touch events being delayed (sometimes up to a second)?

I'm working on a game, and I'm using a CAEAGLLayer backed UIView subclass to present the game engine. Touch handling is done using -touchesBegan:withEvent: et. al.
Everything works fine, except that very rarely, if one of the on-screen controls is tapped rapidly, -touchesBegan:withEvent: doesn't get called for somewhere between 0.1 and 1-2 seconds. This happens maybe one in 20 times, and only if you tap the screen rapidly (4-5 times) first. It seems to be more likely to happen if I am also holding down another finger on a different control on the screen.
Thinking that it was something to do with my own code, I subclassed UIApplication so I could add a logging statement to -sendEvent:. When the laggy touch happens, -sendEvent: doesn't get called until some period of time after the touch has started, so it the touch handling code inside my UIView subclass doesn't appear to be at fault.
Does anyone have any idea what's going on here (other than iOS having some obscure bug)? Is there some sort of internal "events queue" that makes event delivery become laggy when it fills up? Has anyone else experienced this?
Touch events are only dispatched in the main UI run loop, and sometimes only when the main run loop goes idle for a bit. So if your app is busy handling several previous touch events in a row without taking a break, the main UI run loop might be saturated, and thus not get any further touch events until done with the current stuff.
Touch events also have time stamps. So you can check if they're coming too fast (faster than your event handlers and resulting UI updates can run), and skip or combine some of the event handlers, as appropriate for your app, if you want the app to stay maximally responsive.

Resources