2010-12-23 7 views
20

iPhone 응용 프로그램에서 UITabBar를 사용하려고했지만 한 가지 예외는 있습니다. 동기화 작업이 진행되는 동안 회전시키고 싶은 "동기화"버튼이 있습니다. 코어 애니메이션 CALayer 마스크 애니메이션 성능

alt text

는 불행하게도이 사용자 지정 탭 표시 줄을 생성하는 데 의미가 있지만, 여기서는도가 어느 쪽도 없다 : 나는 코어 애니메이션을 사용하여 구현 된 애니메이션이 멋진 보인다. 문제는 애니메이션을 적용하는 동안 화면의 애니메이션 (UITableView 스크롤, MKMapView 패닝 및 핀 놓기 등)의 성능에 부정적인 영향을줍니다. 내 테스트 장치는 iPhone 4입니다.

문제는 어떻게 보일까요? 탭 표시 줄을 구현했습니다. UITabBar와 매우 비슷한 것을 얻고 싶었습니다. 아이콘에 PNG를 제공하고 알파 채널을 사용하여 배경 이미지를 마스킹하여 일반 및 강조 표시 상태를 만듭니다. 당신은 내가 또한 그림자 레이어를 추가 한 볼 수 있습니다 위의 스크린 샷을 단순하지만 내가 코드에서 내가의 그림자 층을 제거하는 것이 제거 :

// Inside a UIView subclass' init method... 

// Create the mask layer by settings its contents as our PNG icon. 
CALayer *maskLayer = [CALayer layer]; 
maskLayer.frame = CGRectMake(0, 0, 31, 31); 
maskLayer.contentsGravity = kCAGravityCenter; 
maskLayer.contentsScale = [[UIScreen mainScreen] scale]; 
maskLayer.rasterizationScale = [[UIScreen mainScreen] scale]; 
maskLayer.contents = (id)symbolImage.CGImage; 
maskLayer.shouldRasterize = YES; 
maskLayer.opaque = YES; 

fgLayer = [[CALayer layer] retain]; 
fgLayer.frame = self.layer.frame; 
fgLayer.backgroundColor = [UIColor colorWithImageNamed:@"tabbar-normal-bg.png"].CGColor; 
fgLayer.mask = maskLayer; // Apply the mask 
fgLayer.shouldRasterize = YES; 
fgLayer.opaque = YES; 

[self.layer addSublayer:fgLayer]; 

은 (참고 : 나는의 CALayer의 mask 속성이 이루어진다. . 그래서이 모든 성능을 제외하고 잘 작동

- (void)startAnimating { 
    CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath: @"transform"]; 
    CATransform3D transform = CATransform3DMakeRotation(RADIANS(179.9), 0.0, 0.0, 1.0); 
    animation.toValue = [NSValue valueWithCATransform3D:transform]; 
    animation.duration = 5; 
    animation.repeatCount = 10000; 
    animation.removedOnCompletion = YES; 
    [fgLayer.mask addAnimation:animation forKey:@"rotate"]; // Add animation to the mask 
} 

: 그것은 관련해서는 안가, 애니메이션 된 동기 아이콘)

는 단순히 마스크 레이어를 회전, 애니메이션합니다. Google에서 이미 레이어를 래스터 화/불투명하게 만드는 팁을 보았습니다. 도움이되지 않았습니다.

저는 마스크 레이어를 범인으로 파악했습니다.

alt text

성능도 이전과 마찬가지로 나쁜 : 나는 마스크 층을 꺼내 단지 대신 마스크의 fgLayer를 회전 할 때 확실히 년대 내가 갈거야 영향을 미치지하지만, 성능은 훌륭합니다 마스크 대신 fgLayer을 회전하는 경우 마스크가 적용됩니다.

그래서 애니메이션의 각 프레임이 느려지는 마스크를 재구성해야한다면 더 나은 성능을 발휘하는 비슷한 효과를 얻기 위해 사용할 수있는 다른 기술이 있습니까? 마스크 레이어에 이미지 대신 패스를 사용 하시겠습니까? 아니면 좋은 성능을 얻으려면 OpenGL이나 뭔가를 사용해야합니까?

UPDATE : 더 마스크가 둔화이라는 생각을 강화, 내 동료가 내용처럼 이미지와의 CALayer를 회전하려고 제안 -/OA 마스크 w 위의 내 예제와 너무 유사 - 성능 그런 식으로도 좋았습니다. 그래서 나는 그저 단색 (그라데이션 없음)을 할 수는 있지만 좋은 임시 해결책이 될 수 있습니다. 제안

답변

15

브렌트 : 환영합니다, 그래서 나는 아직도

가 왜 레이어 마스크를 사용해야합니까,하지만 좋은 성능을 가진 마스크를 회전 달성 싶어요? 마스크 레이어를 하위 레이어로 변환 할 수 없습니까? 이미지에 적절한 알파가 있는지 확인하고 CGImageRef를 레이어의 내용으로 사용하면됩니다.

다른 하나.나는 아직 이유를 알지 못했지만 최상층이 아닌 각 층에 shouldRasterize를 적용 할 때 성능 문제를 발견했습니다. 마스크 레이어의 setShouldRasterize : YES에 대한 참조를 제거하면 전혀 도움이되지 않습니다.

+0

답안의 두 번째 부분은 해결책이었습니다. 하위 레이어 대신 최상위 레이어에'shouldRasterize'를 설정해야했습니다. 이것은 마스크가없는 것만 큼 성능이 좋은 것처럼 보입니다. 내가 마스크가 필요한 이유는 간단한 그라디언트로 간단한 PNG 아이콘을 "채워"시각적 인 흥미를 더할 수 있기 때문입니다. 기본 UITabBar가이 작업을 수행하므로 동일한 작업을 수행하려고합니다 (그러나 노란색 임). –

+0

쿨, 브렌트. 다행이었습니다. 당신이 문제의 * 이유 *에 대한 통찰력을 얻는다면, 나는 알고 싶어합니다. ;-) –

+0

나는 왜 그런지 알고 싶다. 또한, 최상위 레이어를 래스터 화하는 방법이 실제로 마스크 애니메이션의 성능을 향상시키는 방법을 알고 싶습니다. 그것은 여전히 ​​내가 원하는 것을하고 있습니다. 마스크가 돌아가는 동안 백킹 그래디언트 이미지는 고정되어 있습니다. 애니메이션이 시작되기 전에 실제로 각 프레임의 비트 맵을 미리 계산합니까? 마술처럼 보입니다. 이 경우 나는 마술을 좋아한다. :) –

7

하나의 접근법은 마스크로 사용할 CAShapeLayer을 만드는 것입니다. 베 지어 경로를 사용하여 "동기화"아이콘의 버전을 만드는 데 많은 노력을 기울이지 만 셰이프 레이어는 많이 발생합니다 비트 맵보다 변환 당 비용이 낮습니다. 불행히도 회전이 성능 문제가 발생하는 곳인지 확신 할 수 없습니다. 대부분의 지연을 일으키는 마스킹 일 수 있습니다.이 경우 거의 이점을 얻기 위해 모든 벡터화 작업을 수행하게됩니다. 아이콘 회전 애니메이션의 모든 프레임의 필름을 만들고 간단하게 탭 표시 줄에 UIImage 애니메이션 것을 표시 :

나는 최선의 해결책이 UIImage의 애니메이션 기능을 사용하는 것입니다 생각합니다. 가장 세련된 솔루션은 아니지만 메일 및 메모 휴지통의 여러 가지 애니메이션 ("삭제"아이콘 및 여러 가지 활동 표시기 등)이 동일한 방식으로 구현됩니다.

+2

답변 주셔서 감사합니다 - 애니메이션의 필름 스트립을 사용하는 것은 확실히 제가 생각하고있는 것이지만 많은 작업 + 파일 공간처럼 들렸습니다. 운 좋게 * superlayer *에서'shouldRasterize'가 예상 한 성능을 달성 한 것 같습니다. –

+0

대답에서 "shouldRasterize를 NO로 설정"하여 문제가 해결 된 것 같습니다. – Shuo

관련 문제