2016-08-03 51 views
1

從主視圖中刪除子視圖(子視圖「變暗」父視圖,因此爲什麼稱爲dimView)我使用動畫;它基本上移向屏幕的底部,並最終在屏幕的子視圖:爲什麼在調用主線程的閉包時忽略了我的動畫?

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") 

然後通過事件驅動的功能,我把這個動畫像這樣:

@IBAction func done(sender: AnyObject) { 

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

     removingAnimation(dimView) 
     Delay.delay(0.4){ 

      dimView.removeFromSuperview() 
     } 

    } 
} 

這是我的延時類:

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

} 

當我運行在主線程此閉合(這是串行線,並應以串行方式執行任務),我的動畫被忽略,dimView爲r一次從視圖層次中挖掘出來。但是,當我在全局併發線程上運行閉包時,不會忽略動畫,代碼將成功刪除層次結構的dimView。但是這是非法的,因爲你必須從主線程訪問UIKit。

您能否向我解釋當在主線程上調用閉包時問題是什麼?並可能解決我的問題?

感謝

回答

3

的問題是,你要轉換的0.4delayInt,這是0。我建議用

Int64(delay * Double(NSEC_PER_SEC)) 

更換參考

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

作爲進一步的改進,雖然,而不是觸發去除一定時間過去之後,我會完成後讓動畫告訴。最簡單的,你可以使用塊基地UIView動畫:

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

或者,如果你必須使用CABasicAnimation,指定其delegate,然後實現animationDidStop委託方法去除的觀點:

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

順便說一句,以上所有假設您沒有爲dimView指定自動佈局約束。如果有,而不是通過更改frame相關屬性進行動畫製作,則應修改這些約束,然後將該動畫製作爲layoutIfNeeded()

相關問題