iOS 5.xv 6.x의 차이점은 말할 수 없지만 CADisplayLink
을 사용하면 모든 반복마다 "x 픽셀/점 이동"과 같은 코드를 하드 코딩하지는 않지만, 대신 timestamp
(또는 더 정확하게는 내 timestamp
과 현재 timestamp
사이의 델타)를 확인하고 경과 된 프레임 수를 기준으로 위치를 계산합니다. 그런 식으로 프레임 속도는 모션의 속도에 영향을 미치지 않고 단지 부드러움에 영향을줍니다. (그리고 30과 29의 차이는 구별 될 가능성이 높습니다.)
는 CADisplayLink Class Reference에서 인용하자면 :
디스플레이 링크가 실행 루프와 연관되면, 대상의 선택이 될 때 호출되는 화면의 내용을 업데이트해야합니다. 대상에서 디스플레이 링크의 timestamp 속성을 읽으면 이전 프레임이 표시된 시간을 검색 할 수 있습니다. 예를 들어, 동영상을 표시하는 응용 프로그램은 타임 스탬프를 사용하여 다음에 표시 할 비디오 프레임을 계산할 수 있습니다. 자체 애니메이션을 수행하는 응용 프로그램은 시간 소인을 사용하여 다가오는 프레임에 표시되는 객체의 위치와 방법을 결정할 수 있습니다. duration 속성은 프레임 사이의 시간을 제공합니다. 응용 프로그램에서이 값을 사용하여 디스플레이의 프레임 속도, 다음 프레임이 표시 될 대략적인 시간을 계산하고 다음 프레임이 표시되도록 준비 될 수 있도록 그리기 동작을 조정할 수 있습니다. 임의의 예를 들어
,
here 나는 매개 변수로 경과 한 시간 (초)을 사용하여
UIBezierPath
애니메이션을하고있다. 당신이
UIImage
프레임의 순서를 처리하는 경우 다음과 같이
또는이 양자 택일로, 당신은 프레임 수를 계산 수 :
@property (nonatomic) CFTimeInterval firstTimestamp;
- (void)handleDisplayLink:(CADisplayLink *)displayLink
{
if (!self.firstTimestamp)
self.firstTimestamp = displayLink.timestamp;
CFTimeInterval elapsed = (displayLink.timestamp - self.firstTimestamp);
NSInteger frameNumber = (NSInteger)(elapsed * kFramesPerSecond) % kMaxNumberOfFrames;
// now do whatever you want with this frame number
}
을 프레임 손실 위험 방지하기 위해, 또는 더 나은 아직, 진행 이 작업을 60fps로 실행하고 프레임을 업데이트해야하는지 여부를 결정하면 프레임을 놓을 위험이 줄어 듭니다.
- (void)handleDisplayLink:(CADisplayLink *)displayLink
{
if (!self.firstTimestamp)
self.firstTimestamp = displayLink.timestamp;
CFTimeInterval elapsed = (displayLink.timestamp - self.firstTimestamp);
NSInteger frameNumber = (NSInteger)(elapsed * kFramesPerSecond) % kMaxNumberOfFrames;
if (frameNumber != self.lastFrame)
{
// do whatever you want with this frame number
...
// now update the "lastFrame" number property
self.lastFrame = frameNumber;
}
}
그러나 자주는, 프레임 번호는 전혀 필요하지 않습니다.예를 들어, 원에 UIView
를 이동, 당신은 같은 것을 할 수 있습니다 당신은 프레임 속도를 측정하는 계측기를 사용하는 경우, 그런데
- (void)handleDisplayLink:(CADisplayLink *)displayLink
{
if (!self.firstTimestamp)
self.firstTimestamp = displayLink.timestamp;
CFTimeInterval elapsed = (displayLink.timestamp - self.firstTimestamp);
self.animatedView.center = [self centerAtElapsed:elapsed];
}
- (CGPoint)centerAtElapsed:(CFTimeInterval)elapsed
{
CGFloat radius = self.view.bounds.size.width/2.0;
return CGPointMake(radius + sin(elapsed) * radius,
radius + cos(elapsed) * radius);
}
을, 그것이 정말로 것보다 느리게 보일 수 있습니다 장치. 정확한 프레임 속도를 얻으려면 matt의 설명에 따라 릴리스 빌드가있는 실제 장치에서 프로그래밍 방식으로 측정해야합니다.
멋진 아이디어! 따라서 onTick 메서드에서 타임 스탬프를 설정 한 다음 다음 타임 스탬프에 다시 타임 스탬프를 적용한 다음 0.03333 초 차이가 나는지 비교해보십시오. 내가하지 않으면? 당신은 당신의 개념에 대해 자세히 설명 할 수 있습니까? – objectiveccoder001
@ objectiveccoder001 절대적으로 30fps가 필요한 몇 가지 이유가 있다면, 그렇습니다. 그렇게 할 수 있습니다. 경과 한 시간을 기준으로 프레임 번호를 결정할 수있는 코드 샘플을 참조하십시오. 그러나 많은 애니메이션은 그렇게 할 필요가 없지만 경과 시간을 기준으로 새로운 위치를 계산할 수 있으며 30fps (29 vs 59 vs 등)로 제한되는 이유가 없습니다. – Rob
굉장! 정말 고맙습니다. kMaxNumberOfFrames는 무엇입니까? – objectiveccoder001