2015-11-26 6 views
5

in meinem Viewcontroller ich habe:UIImage nicht, wenn sie zu CALayer in einem Background angezeigt

@IBOutlet var worldmapview: Worldmapview! 


var eventLayer:CALayer=CALayer(); 

und einige Funktion:

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 meinem viewDidAppear(animated: Bool) method ich versuche, das Bild in worldmapview zu zeigen

der folgende Code funktioniert einwandfrei ohne Hintergrundaufgaben. Das Bild wird sofort angezeigt.

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

in einer Hintergrundaufgabe und erfrischend in der Hauptaufgabe es nicht für mich funktioniert. Das Bild wird nicht angezeigt. Nach einer Weile erscheint es, aber nicht immer.

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

      }) 
     }) 

aktualisieren

ich den Code mit einem neuen CAShapelayer aktualisiert hinzugefügt, um die gleiche Art und Weise, die sofort anzeigt. Ich verstehe den Unterschied nicht. Das Bild wird nicht angezeigt, wenn es in einer Hintergrundaufgabe erstellt wird.

UPDATE2

erkannte ich etwas verwirrend für mich zusätzlich: folgenden Code ohne Hintergrundaufgabe arbeitet, wie bereits beschrieben:

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

Aber die letzte Zeile zu aktivieren, wird das Bild nicht angezeigt. Wahrscheinlich hat es etwas damit zu tun? Es scheint so, als ob der Inhalt des Kalenders verschwunden ist?

+0

Können Sie bestätigen, dass 'self.create_picture_layer ("mypicpath")' synchron ist, und sofort nicht zurück? – SwiftArchitect

+0

Sie haben Recht. Ich habe den Code aktualisiert. Ich schrieb "es ist leer" und es läuft in diese Situation. Hast du einen Hinweis, wie du das lösen kannst? Ich möchte die Ebene im Hintergrund vorbereiten und die Ansicht nachträglich aktualisieren, wenn die Ebene hinzugefügt wird. Wie geht das ? –

+0

Sie sollten die Benutzeroberfläche im Hintergrund-Thread nicht ändern. – kelin

Antwort

1

Wie ich es verstehe, erstellen Sie CALayer im Hintergrund, und Hinzufügen dieser Ebene zur UI-Hierarchie im Hintergrund.

Wäre es vernünftig zu denken, dass alle UI-Modifikationen im main Thread stattfinden sollen? Wenn ja, versuchen Sie dies:

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

Danke für die Hilfe, aber es hat nicht funktioniert. Ich habe meinen Code aktualisiert. Dort können wir sehen, dass meine neu hinzugefügte Kreisform sofort erscheint, aber die Bilderform nicht. Frage ist warum? –

+0

Was ist hinter "getImage"? Haben Sie versucht, ein Bild in einem Bestandskatalog anzuzeigen? – SwiftArchitect

+0

Ich habe gerade die Frage mit dem Code von getImage() aktualisiert. Ich habe es nicht mit Asset Catalog versucht. Das wird auch in meiner Situation nicht möglich sein, weil ich nicht weiß, welche Bilder da sind. Sie befinden sich in einem bestimmten Ordner auf dem Gerät. –