Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

My custom UI elements are not being updated while UIScrollView is scrolled

I have a spinning circle UI element that is updated by an NSTimer. I also have a UIScrollView that would 'block' the spinning circle while being scrolled. That was expected, because the timer and the scroll view where both in the same thread.

So I put the timer in a separate thread which basically works great! I can see it working because NSLogs keep coming even while scrolling.

But my problem is that my spinning circle is still stopping on scrolling! I suspect redrawing is halted until the next iteration of the main thread's run loop (?). So even if its angle is changed all the time, it might not be redrawn...

Any ideas what I can do? Thanks!

like image 381
Sebastian Avatar asked Nov 05 '10 20:11

Sebastian


People also ask

How do I make my UI view scrollable?

You cannot make a UIView scrollable. That's what UIScrollView is for. However if you are using storyboards you can try to add constraints to the view so when you rotate the device the content remains inside the viewable area.

What is UIScrollView in swift?

A view that allows the scrolling and zooming of its contained views.

How does UIScrollView work?

A floating-point value that determines the rate of deceleration after the user lifts their finger. We can assume that this rate indicates how much the scroll velocity will change after one millisecond (all UIScrollView values are expressed in milliseconds, unlike UIPanGestureRecognizer ).


2 Answers

While scrolling, the main thread's run loop is in UITrackingRunLoopMode. So what you need to do is schedule your timer in that mode (possibly in addition to the default mode). I believe NSRunLoopCommonModes includes both the default and event tracking modes, so you can just do this:

NSTimer *timer = [NSTimer timerWithTimeInterval:0.42 target:foo selector:@selector(doSomething) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

By the way, you should do this all on the main thread. No need to spawn a background thread (unless each timer invocation is going to do some lengthy processing).

like image 79
Daniel Dickison Avatar answered Sep 25 '22 09:09

Daniel Dickison


UIScrollView doesn't just block NSTimers, it blocks the entire main thread. And UIKit objects should be accessed on the main thread only (and, often, are limited in unpredictable ways if you try to dodge round that restriction), which is probably why — even if you have a clock coming in from an external thread — you're unable to post updates.

It's a bit of a dodge, but is there any way your animation can be achieved with CoreAnimation? Things tied to that continue working irrespective of what's happening in the main thread.

like image 37
Tommy Avatar answered Sep 24 '22 09:09

Tommy