2015-11-26 14 views
5

w moim viewcontroller mam:UIImage nie jest wyświetlany po dodaniu do CALayer w backgroundtask

@IBOutlet var worldmapview: Worldmapview! 


var eventLayer:CALayer=CALayer(); 

a niektóre funkcje:

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; 
    } 
} 

W moim viewDidAppear(animated: Bool) method staram się pokazać obraz w worldmapview

Poniższy kod działa poprawnie bez żadnych zadań w tle. Obraz jest wyświetlany natychmiast.

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

w zadaniu tła i odświeżanie w głównym zadaniu nie działa dla mnie. Zdjęcie nie jest wyświetlane. Po chwili pojawia się, ale nie zawsze.

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

      }) 
     }) 

Aktualizacja

I uaktualniony kod z nowym CAShapelayer dodany w ten sam sposób, który jest natychmiast wyświetlania. Nie rozumiem różnicy. Obraz nie jest wyświetlany, jeśli został utworzony w zadaniu tła.

Update2

uświadomiłem sobie coś mylące dla mnie dodatkowo: następujący kod bez zadania w tle działa jak już opisano:

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

Ale aktywacji ostatni wiersz, obraz nie pojawia. Prawdopodobnie ma to coś wspólnego z tym? Wygląda na to, że zawartość kalejdra zniknęła?

+0

Czy możesz potwierdzić, że 'self.create_picture_layer (" mypicpath ")' jest synchroniczne i nie od razu zwraca? – SwiftArchitect

+0

Masz rację. Zaktualizowałem kod. Napisałem "puste" i wpada w tę sytuację. Czy masz jakąś wskazówkę, jak to rozwiązać? Chciałbym przygotować warstwę w tle i odświeżyć widok po dodaniu warstwy. Jak to zrobić ? –

+0

Nie powinieneś modyfikować interfejsu użytkownika w wątku tła. – kelin

Odpowiedz

1

Rozumiem, że tworzysz CALayer w tle, i, dodając tę ​​warstwę do hierarchii UI również w tle.

Czy byłoby rozsądnie myśleć, że wszystkie modyfikacje interfejsu mają się zdarzyć w wątku main? Jeśli tak, spróbuj tego:

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

Dzięki za pomoc, ale to nie zadziałało. Zaktualizowałem mój Kodeks. Tam widzimy, że mój nowy dodany krąg pojawia się od razu, ale obraz nie jest. Pytanie brzmi: dlaczego? –

+0

Co kryje się za 'getImage'? Czy próbowałeś z obrazem obecnym w Katalogu aktywów? – SwiftArchitect

+0

Właśnie zaktualizowałem pytanie kodem getImage(). Nie próbowałem z Katalogiem zasobów. To też będzie możliwe w mojej sytuacji, ponieważ nie wiem, które zdjęcia tam są. Są w określonym folderze na urządzeniu. –

Powiązane problemy