2016-08-03 14 views
1

Um eine Unteransicht aus der Hauptansicht zu entfernen (die Unteransicht "dimmt" die Elternansicht, weshalb sie DimView genannt wird) verwende ich eine Animation; es bewegt sich im Grunde die Subview in Richtung der Unterseite des Bildschirms und schließlich aus dem Bildschirm:Warum wird meine Animation beim Aufrufen eines Abschlusses im Hauptthread ignoriert?

let centerY = CGRectGetMidY(view.bounds) 
    let animation: CABasicAnimation = CABasicAnimation(keyPath: "position") 
    animation.removedOnCompletion = false 
    animation.fillMode = kCAFillModeForwards 
    animation.fromValue = NSValue(CGPoint: view.center) 
    animation.toValue = NSValue(CGPoint: CGPoint(x: view.center.x, y: 4 * centerY)) 
    animation.duration = 0.2 
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) 
    dimView.layer.addAnimation(animation, forKey: "DimRemovingAnimation") 

dann durch eine Funktion Event Driven ich diese Animation wie so nennen:

@IBAction func done(sender: AnyObject) { 

    let dimView = view.viewWithTag(1) 
    if let dimView = dimView { 

     removingAnimation(dimView) 
     Delay.delay(0.4){ 

      dimView.removeFromSuperview() 
     } 

    } 
} 

Das ist meine Verzögerungsklasse :

class Delay{ 



class func delay(delay: Double, block:() ->()){ 


    let when = dispatch_time(DISPATCH_TIME_NOW, Int64(Int(delay) * Int(NSEC_PER_SEC))) 

    dispatch_after(when, dispatch_get_main_queue(), block) 
} 

} 

Als ich diesen Verschluss auf dem Haupt-Thread ausgeführt werden (das ein serieller Thread ist, und soll Aufgaben auf serielle Weise ausführen) meine Animation ignoriert und dimView ist r aus der Sichthierarchie sofort entfernt werden. Wenn ich den Abschluss für einen globalen gleichzeitigen Thread ausführen, wird die Animation jedoch nicht ignoriert und der Code entfernt DimView der Hierarchie erfolgreich. Dies ist jedoch illegal, da Sie über den Hauptthread auf UIKit zugreifen müssen.

Können Sie mir bitte erklären, was das Problem ist, wenn die Schließung auf dem Hauptgewinde aufgerufen wird? und eine mögliche Lösung für mein Problem?

Dank

Antwort

3

Das Problem ist, dass Sie delay von 0.4 zu einem Int konvertieren, die 0 ist. Ich würde vorschlagen, den Verweis auf

Int64(Int(delay) * Int(NSEC_PER_SEC)) 

mit

Int64(delay * Double(NSEC_PER_SEC)) 

Als weitere Verfeinerung zu ersetzen, aber anstatt das Auslösen der Entfernung nach einer gewissen Zeit vergangen ist, würde ich Lassen Sie die Animation Sie erzählen, wenn es fertig ist. Einfachste, können Sie die Blockbasis UIView Animation verwenden:

UIView.animateWithDuration(0.2, delay: 0.0, options: .CurveEaseIn, animations: { 
    dimView.center = CGPoint(x: self.view.center.x, y: 4 * centerY) 
}, completion: { finished in 
    dimView.removeFromSuperview() 
}) 

Oder, wenn Sie CABasicAnimation verwenden müssen, seine delegate angeben und dann animationDidStop Delegatmethode implementieren, um die Ansicht zu entfernen:

override func animationDidStop(anim: CAAnimation, finished flag: Bool) { 
    dimView.removeFromSuperview() 
} 

Alle oben genannten Annahmen gehen davon aus, dass Sie keine automatischen Layoutbeschränkungen für dimView angegeben haben. Wenn Sie die Eigenschaften nicht ändern, sondern animieren, müssen Sie diese Einschränkungen ändern und anschließend den Aufruf an layoutIfNeeded() animieren.