UIImage not showing when added to CALayer in background table

in my vision controller, I have:

@IBOutlet var worldmapview: Worldmapview! var eventLayer:CALayer=CALayer(); 

and some function:

 func create_picture_layer(pathtopic:String) -> CALayer { let bm=getImage(pathtopic,fBitmapsizeSelected: 100)!; var calayer_for_picture=CALayer(); calayer_for_picture.frame=CGRectMake(100, 100, 100, 100); calayer_for_picture.contents = bm.CGImage; return calayer_for_picture; } func createCircleShape(x:CGFloat,y:CGFloat, size:CGFloat) -> CAShapeLayer { var test2:UIBezierPath=UIBezierPath(ovalInRect: CGRectMake(x - size/2, y - size/2, size, size)); var shapelayer:CAShapeLayer=CAShapeLayer(); shapelayer.backgroundColor=UIColor.clearColor().CGColor; //shapelayer.frame=CGRectMake(0, 0, 300, 300); shapelayer.fillColor=UIColor.darkGrayColor().CGColor; shapelayer.path=test2.CGPath; shapelayer.opaque=true return shapelayer; } func getImage(simagename: String, fBitmapsizeSelected:CGFloat) -> UIImage?{ var sPathToImage:String=AppProperties.sharedInstance.sPicturePath + simagename; let checkValidation = NSFileManager.defaultManager() if (!checkValidation.fileExistsAtPath(sPathToImage) || simagename.equals("")){ // Path to unknown image let sunknownimagename:String = "na/na.jpa"; sPathToImage=AppProperties.sharedInstance.sPicturePath + sunknownimagename; } let bm:UIImage=UIImage(contentsOfFile: sPathToImage)!; var bMapScaled:UIImage; if(!bm.isEqual(nil)){ let newSize:CGSize=CGSizeMake(fBitmapsizeSelected, fBitmapsizeSelected); bMapScaled = bm.imageByScalingToSize(newSize,contentMode: UIViewContentMode.ScaleAspectFill)!; return bMapScaled; }else{ return nil; } } 

In my viewDidAppear(animated: Bool) method I'm trying to show an image in worldmapview

The following code works fine without any background tasks. The image is displayed immediately.

 // works let thepicturelayer=create_picture_layer("mypicpath") eventLayer.addSublayer(thepicturelayer); worldmapview.layer.addSublayer(eventLayer); eventLayer.setNeedsDisplay(); 

in the background task and lighting in the main task this does not work for me. Image is not displayed. After a while appears, but not always.

 // doesn't work let qualityOfServiceClass = QOS_CLASS_BACKGROUND let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0) dispatch_async(backgroundQueue, { // geht auch mit Eventlayer let thepicturelayer=self.create_picture_layer() // This Shape doesn't appear. let circleshapelayer=self.createCircleShape(200, y: 200, size: 20) // This shape appears immediatelly. self.eventLayer.addSublayer(thepicturelayer); self.eventLayer.addSublayer(circleshapelayer); dispatch_async(dispatch_get_main_queue(),{ //assert(self.eventLayer.sublayers?.count > 0,"no layers in eventLayer !") // just added self.worldmapview.layer.addSublayer(self.eventLayer); //assert(self.worldmapview.layer.sublayers!.count > 0,"no layers in worldmapview!" ) // just added let sublayers=self.eventLayer.sublayers; if sublayers != nil { for l in self.eventLayer.sublayers! { l.setNeedsDisplay() } } //self.updateWorldMapGUI(); self.worldmapview.layer.addSublayer(self.eventLayer); //thepicturelayer.setNeedsDisplay(); //circleshapelayer.setNeedsDisplay(); self.eventLayer.setNeedsDisplay(); }) }) 

Update

I updated the code with a new CAShapelayer added in the same way that displays immediately. I do not understand the difference. The image does not appear when created in the background job.

UPDATE2

I understood something additionally confusing for me: The following code without a background task works as already described:

  let thepicturelayer=create_picture_layer() eventLayer.addSublayer(thepicturelayer); worldmapview.layer.addSublayer(eventLayer); eventLayer.setNeedsDisplay(); //thepicturelayer.setNeedsDisplay(); // When adding this, the picture is not shown. 

But when the last line is activated, the image does not appear. Perhaps this is somehow connected with this? Does this killer seem to be missing?

+5
source share
1 answer

As I understand it, you create a CALayer in the background and add this layer to the user interface hierarchy in the background.

Would it be prudent to think that all user interface changes should happen in the main thread? If yes, try the following:

 let qualityOfServiceClass = QOS_CLASS_BACKGROUND let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0) dispatch_async(backgroundQueue, { let thepicturelayer=self.create_picture_layer() dispatch_async(dispatch_get_main_queue(),{ self.eventLayer.addSublayer(thepicturelayer); assert(self.eventLayer.sublayers) // just added self.worldmapview.layer.addSublayer(self.eventLayer); assert(self.worldmapview.layer.sublayers) // just added self.worldmapview.setNeedsDisplay() }) }) 
+1
source

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


All Articles