How to do two user interface updates at the same time?

From what I can tell by reading the Apple documentation, UI updates can only be run in the main thread.

My application does some visualization in the upper half of the screen and has a table view in the lower half. If the user scrolls the table and the upper half by itself, the table is locked for half a second or so. Is there a way to improve the situation?

+6
source share
2 answers

If drawing a view takes a noticeable amount of time, I would suggest drawing it into an image in the background thread when updating and having the view just draw the image. This will prevent blocking of the main thread.

The following code shows how to create and draw in the context of a bitmap from a background stream. When you call the updateInBackground method, it will create a new background thread that creates and draws in context, and then creates an image using that context. If you put this in a custom subclass of UIImageView , the image will be automatically drawn on the screen.

 - (void)updateInBackground { [self performSelectorInBackground:@selector(_drawInBackground:) withObject:[NSValue valueWithCGRect:self.bounds]]; } - (void)_drawInBackground:(NSValue *)boundsValue { NSAutoreleasePool *pool = [NSAutoreleasePool new]; CGRect bounds = [boundsValue CGRectValue]; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); if(!colorSpace) { [pool drain]; return; } CGContextRef context = CGBitmapContextCreate(NULL,bounds.size.width, bounds.size.height, 8, bounds.size.width * 32, colorSpace, kCGImageAlphaPremultipliedFirst); CGColorSpaceRelease(colorSpace); if(!context) { [pool drain]; return; } CGContextConcatCTM(context, CGAffineTransformMake(1,0,0,-1,0,bounds.size.height)); // do drawing here CGImageRef image = CGBitmapContextCreateImage(context); [self performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageWithCGImage:image] waitUntilDone:YES]; CGImageRelease(image); CGContextRelease(context); [pool drain]; } 

When drawing in a background thread, you can NOT use UIKit objects and methods. All drawings must be performed using quartz functions . If you need to use UIKit, a background thread can call a method in the main thread to make this section of the drawing:

 [self performSelectorOnMainThread:@selector(drawInMainThread:) withObject:[NSValue valueWithPointer:context] waitUntilDone:YES]; - (void)drawInMainThread:(NSValue *)value { UIGraphicsPushContext((CGContextRef)[value pointerValue]); // do drawing using UIKit UIGraphicsPopContext(); } 
+1
source

It seems that drawing the upper half takes some time. Do you control it with tools?

It is important to remember that if you want smooth 60FPS scrolling, your rendering (and any other processor in the main thread) should take less than 16 MS per cycle, otherwise you will start to drop frames.

0
source

Source: https://habr.com/ru/post/894054/


All Articles