0

I have a UIView that sets a timer and each firing it generates a UIImage on a background queue (priority .userInitiated), and when finished (measured to take between 1-2 milliseconds, it pushes to the main queue and updates a UIImageView's image.

This creates a smooth animation effect (e.g. if the Timer is configured to fire 30 times per second). Touching the screen however either slows down or completely shuts down the updating. I removed my overrides of touchesBegan,Moved,Ended and any GestureRecognizers to ensure that I wasn't doing anything expensive. Simply touching the screen (especially dragging quickly) prevents the UI updating.

I watched this and googled as many SO posts as I can but I'm completely stuck on this.

Here is a reproduction of the problem. Run the app and it will display a stripped down rendering of a basic project. From there, you can drag/touch the screen and notice the frames will either slow down to a crawl or completely stop.

Github Repro

Alex Bollbach
  • 4,370
  • 9
  • 32
  • 80
  • Personally I'd use a [`CADisplayLink`](https://developer.apple.com/documentation/quartzcore/cadisplaylink), but you need to [configure it so it's not affected by scrolling](https://stackoverflow.com/questions/2524347/cadisplaylink-stops-updating-when-uiscrollview-scrolled) – MadProgrammer Nov 05 '18 at 03:50
  • sure, but i'm still running the intensive processing on a background queue and simply updating the UIImageView's image on the main queue. apple even suggests one can use both a Timer and a DisplayLink to do real time animating like this. I'll try substitution a DisplayLink but using a Timer specifically should not be the bottleneck. – Alex Bollbach Nov 05 '18 at 03:56
  • As I understand it, both (by default) `CADisplayLink` and `Timer` run on the main `runLoop`, so any UI interaction could "stall" them - I might be over simplifying this though – MadProgrammer Nov 05 '18 at 03:58
  • well, something relevant here is that I added a print statement in the line that pushes to the main queue and updates the UIImageView. when i start dragging, its stilled fired. So the Timer keeps firing, the processing is succeeding while I'm dragging, I just don't see the results. So the problem appears to be "downstream" of the timer firing and rendering. – Alex Bollbach Nov 05 '18 at 04:00
  • Possibly because the "paint" cycles are suspended? I was told in passing about `Timer` running on the main run loop and how would be affected by scrolling :/ – MadProgrammer Nov 05 '18 at 04:02
  • what are "paint" cycles and how do i unsuspend them lol – Alex Bollbach Nov 05 '18 at 04:03
  • i'm not "scrolling" fwiw. no scroll views or gesture recognizers. not even touchesMoved. just dragging on the screen with no hooks or handlers. the UIView is a plain view with an embedded UImageView. – Alex Bollbach Nov 05 '18 at 04:04
  • We're all just discussing theoretical possibilities, without a suitable runnable example, it would be difficult (for me, with my limited experience) to make any "real" suggestion, beyond making use of a `CADisplayLink`, which I've switched to using instead of `Timer` so I configure it's run loop – MadProgrammer Nov 05 '18 at 04:10

0 Answers0