2016-08-03 2 views
1

기본보기에서 하위보기를 제거하려면 (하위보기는 부모보기를 "희미하게합니다", 따라서 dimView라고 부름) 애니메이션을 사용합니다. 이건 내 지연 클래스입니다메인 스레드에서 클로저를 호출 할 때 애니메이션이 무시되는 이유는 무엇입니까?

@IBAction func done(sender: AnyObject) { 

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

     removingAnimation(dimView) 
     Delay.delay(0.4){ 

      dimView.removeFromSuperview() 
     } 

    } 
} 

:이 애니메이션과 같이 호출 이벤트 구동 기능을 통해 다음

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

: 그것은 기본적으로 화면의 아래쪽으로 결국 화면 밖으로 서브 뷰를 이동 :

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

문제는 당신이 0Int0.4delay 변환하고 있다는 점이다. 일정 시간이 경과 한 후에 난 좋겠 불구하고, 추가의 정제로서

Int64(delay * Double(NSEC_PER_SEC)) 

으로

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

에 대한 참조를 대체하기보다는 제거를 트리거 좋을 것 완료되면 애니메이션 에게 말하게하십시오. 당신이 CABasicAnimation를 사용해야하는 경우 뷰 제거, 그 delegate 다음 구현 animationDidStop 위임 방법을 지정,

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

또는 :

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

을 가장 쉬운, 당신은 블록 기반을 UIView 애니메이션을 사용할 수 있습니다 그런데 위의 모든 내용은 dimView에 대한 자동 레이아웃 제약 조건을 지정하지 않았다고 가정합니다. 가지고있는 경우 frame 관련 속성을 변경하여 애니메이션을 적용하는 대신 이러한 제약 조건을 수정 한 다음 호출을 layoutIfNeeded()에 애니메이션으로 적용해야합니다.