2016-08-03 36 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()

相关问题