Reputation: 2937
I have some custom UIControl whose state goes from normal to pressed to selected. By the logic of the application, when the user lifts their finger, the control should be selected, and some view should be loaded. The view is rather large, containing lots of data and complex views. So the result is that when the user lifts their finger, the display freezes for roughly 100-400 milleseconds, then displays what the user expected. The long delay before seeing the control in the selected state feels like an error. In order to fix it I did the following:
-(IBAction)didTapControl:(UIControl*)sender{
sender.selected = YES;
double delayInSeconds = 0.05;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
//perform some long running task
}
}
However, that 0.05 is just a guess, and I may be unnecessarily delaying the views appearance by 0.05. What I really want to happen is for the view to finish refreshing with the button in a selected state, THEN immediately perform the longer running task. Is there a better way to time this action? Should I be using dispatch_after for this?
Upvotes: 0
Views: 70
Reputation: 41801
It sounds like you're probably better served by either dispatch_async() to the main queue, or (in order to handle runloop modes and reentrancy), CFRunLoopPerformBlock().
That will let you return control to the main thread so it can do it's stuff, and then be run once it next gets around to processing events.
Even better, of course, would be if you could avoid doing 400ms of work on the main thread entirely by optimizing your views and view hierarchy.
Upvotes: 1