2012-09-13 3 views
2

specialLayer이라는 하위 계층이있는보기가 있습니다. 불투명도의 암시 적 애니메이션은 다음과 같이 비활성화됩니다.CABasicAnimation이 끝난 후 레이어의 불투명도를 설정할 수없는 이유는 무엇입니까?

self.specialLayer.actions = [NSDictionary dictionaryWithObjectsAndKeys: 
              [NSNull null], @"opacity", nil]; 

이 하위 계층에 액세스하는 방법은 두 가지뿐입니다.

- (void)touchDown { 
    self.specialLayer.opacity = 0.25f; 
} 

- (void)touchUp { 
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
    animation.fromValue = [NSNumber numberWithFloat:self.specialLayer.opacity]; 
    animation.toValue = [NSNumber numberWithFloat:1.0]; 
    animation.duration = 0.5; 
    animation.removedOnCompletion = NO; 
    animation.fillMode = kCAFillModeForwards; 
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 
    [self.specialLayer addAnimation:animation forKey:@"opacity"]; 
} 

이 발생합니다

1) 사용자는() 채 버튼을 누르면 및 -touchDown가 호출됩니다. specialLayer의 불투명도가 즉시 0.25

2) 사용자 해제 버튼과 -touchUp이 호출됩니다. specialLayer의 불투명도가 1.0으로 돌아갑니다

이 시퀀스는 오직 한 번만 작동합니다!

3) 사용자가 버튼을 다시 누르면 (누른 상태) -touchDown이 호출됩니다. 그러나 specialLayer의 불투명도는 화면에서 변경되지 않습니다! self.specialLayer.opacity = 0.25f;이 호출 되더라도 아무 일도 발생하지 않습니다. 불투명도는 1.0f로 유지됩니다.

4) 사용자가 손가락을 들어 올리고 -touchUp이 호출됩니다. specialLayer의 불투명도 JUMPS를 0.25로 설정하고 거기에서 1.0f로 애니메이션을 만듭니다.

NSLog를 검사하여 메서드가이 순서대로 호출되는지 확인했습니다. 그들이하다.

애니메이션 코드의 주석 처리를 제거하고 불투명도를 1.0으로 직접 설정하면 후속 직접 불투명도 변경이 즉시 적용됩니다. 확실히 문제를 일으키는 것은 CABasicAnimation입니다. 암시 적 애니메이션을 비활성화하는 코드를 제거해도이 문제가 발생하지 않습니다.

나는 여기서 무슨 일이 일어나는지 알아낼 수 없다. 불투명도에 대한 CABasicAnimation을 추가 한 후 CALayer가 내가 설정 한 불투명도 값을 반영하지 않는 이유는 무엇입니까? 이거 버그 야?

내가 뭘 잘못하고 있니?

+0

레이어 불투명도가 무엇을 의미합니까? 애니메이션을 추가하기 전에 레이어 불투명도의 최종 값을 설정해야합니다. like layer.opacity = 1.0 – msk

+0

자세한 내용으로 질문을 업데이트했습니다. –

+0

@ ProudMember : 내 대답을 읽었습니까? 맨 처음 문장은 근본적인 문제를 설명합니다. 궁금한 점이 있으면 알려주십시오. –

답변

8

애니메이션의 removedOnCompletionNO으로 설정합니다. 즉, 애니메이션이 완료되면 여전히 레이어에 머물러 있고 렌더링을 위해 여전히 opacity의 값을 제어합니다. 이 코드를 다시 호출하면 새로운 애니메이션이 이전을 대체하여 점프가 발생합니다 (새로 설정 한 0.25f을 시작점으로 사용함).

해결 방법은 removedOnCompletion에서 NO으로 설정을 중지하는 것입니다. 대신 애니메이션을 추가 할 때 레이어의 실제 불투명도를 애니메이션의 끝점과 동일한 값으로 설정해야합니다.

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
// you can omit fromValue since you're setting it to the layer's opacity 
// by omitting fromValue, it uses the current value instead. Just remember 
// to not change layer.opacity until after you add the animation to the layer 
animation.toValue = [NSNumber numberWithFloat:1]; 
animation.duration = 0.5; 
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 
[layer addAnimation:animation forKey:@"opacity"]; 
layer.opacity = 1; // or layer.opacity = [animation.toValue floatValue]; 

그 이유는 방식 때문에 레이어 렌더링 작품이다. CoreAnimation은 레이어 트리를 화면에 렌더링 할 때 모델 트리를 복사하고 프레젠테이션 트리를 생성합니다. 모든 레이어를 복사 한 다음 모든 애니메이션을 적용하면됩니다. 따라서 레이어의 각 애니메이션을 검토하고 시간을 타이밍 함수에 연결하고 결과 진행률을 시작/끝 값 사이의 보간에 연결 한 다음 최종 값을 다시 프레젠테이션 레이어의 속성에 적용합니다.

따라서 레이어에 애니메이션을 영구적으로두면이 애니메이션은 실제 모델 값이 키의 값과 다른 경우 항상 무시합니다. layer.opacity을 몇 번이나 변경해도 상관 없습니다. opacity을 제어하는 ​​애니메이션은 항상 프레젠테이션 목적으로 값을 덮어 씁니다.

애니메이션을 추가 한 후에 layer.opacity을 원하는대로 설정할 수있는 동일한 이유가 있습니다. 애니메이션이 우선 적용되기 때문입니다. 애니메이션이 제거 될 때만 (애니메이션이 완료되면 기본적으로 발생 함) 해당 속성의 모델 값이 다시 사용됩니다.

+0

다소 비슷한 질문이있었습니다 (애니메이션 및 불투명도와 관련이 있습니다). 나는 여기에 대답하려고합니다 : http://stackoverflow.com/questions/12396160/why-do-some-animatable-properties-set-outside-an- 애니메이션 블록을 취하지 않은 효과/12397485 # 12397485. 나는 그 대답에 대해 궁금해. 죄송합니다. 의견을 듣고 옆에있는 당신에게 연락하는 방법을 모르겠습니다 ... – tiguero

관련 문제