Ios 在backgroundtask中将UIImage添加到CALayer时不显示

Ios 在backgroundtask中将UIImage添加到CALayer时不显示,ios,swift,uiimage,calayer,Ios,Swift,Uiimage,Calayer,在我的viewcontroller中,我有: @IBOutlet var worldmapview: Worldmapview! var eventLayer:CALayer=CALayer(); 还有一些功能: func create_picture_layer(pathtopic:String) -> CALayer { let bm=getImage(pathtopic,fBitmapsizeSelected: 100)!; var calayer_for_pi

在我的viewcontroller中,我有:

@IBOutlet var worldmapview: Worldmapview!


var eventLayer:CALayer=CALayer();
还有一些功能:

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;
    }
}
在我的
视图显示(动画:Bool)方法中
我尝试在worldmapview中显示图像

以下代码在没有任何后台任务的情况下运行良好。图像立即显示

// works
let thepicturelayer=create_picture_layer("mypicpath")
eventLayer.addSublayer(thepicturelayer);
worldmapview.layer.addSublayer(eventLayer);
eventLayer.setNeedsDisplay();
在后台任务中,在主任务中刷新,这对我不起作用。图片未显示。过了一会儿,它出现了,但并不总是这样

// 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();

            })
        })
更新

我用同样的方式添加了一个新的CAShapelayer来更新代码,它会立即显示出来。我不明白其中的区别。在后台任务中创建时,不显示图片

更新2

此外,我还意识到一些让我困惑的事情: 以下没有后台任务的代码的工作原理如前所述:

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

但是激活最后一行,图片不会出现。可能跟这有关吧?似乎calayer的内容消失了?

据我所知,您正在后台创建
calayer
,并将该层添加到后台的UI层次结构中

认为所有UI修改都将发生在
main
线程中是否合理?如果是,请尝试以下方法:

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()
    })
})

您能否确认
self.create\u picture\u layer(“mypicpath”)
是同步的,并且不会立即返回?您是对的。我更新了代码。我写了“它是空的”,它就遇到了这种情况。你有什么办法解决这个问题吗?我想在后台准备图层,并在添加图层后刷新视图。怎么做?你不应该在后台线程中修改UI。请看代码。我没有这样做。同样,我可以毫无问题地向CALayers展示UIImages。有人对此有解决方案吗?谢谢你的帮助,但没用。我更新了我的代码。在那里我们可以看到,我新添加的圆圈形状立即出现,但图片形状没有。问题是为什么?在
getImage
后面是什么?您尝试过资产目录中的图像吗?我刚刚用getImage()代码更新了这个问题。我没有尝试使用资产目录。这在我的情况下也是不可能的,因为我不知道那里有哪些图片。它们在设备上的一个特定文件夹中。投票支持该样本的人是否成功地测试了解决方案?我刚刚意识到一些令人困惑的问题,我在UPDATE2下的问题中描述了这一点。可能跟这有关吧?