我一直在這裏工作了一段時間,並徹底搜索了一個解決方案,但無濟於事。這是我想要做的。CALayer上CAlleFrameAnimation的變換屬性不能按預期工作
我有一個用戶可以縮放和平移5秒的UIScrollView。我有一個單獨的CALayer,它不在UIScrollView的頂層。我想縮放和翻譯此CALayer的內容以反映在UIScrollView上發生的縮放和平移。我想通過關鍵幀動畫CAKeyFrameAnimation
實現此目的。當我把它放到代碼中時,縮放按預期發生,但內容的位置被錯誤地偏移。
這是我如何在代碼中做到這一點。假設UIScrollView
代表經過縮放比例和含量偏移下面的方法:
// Remember all zoom params for late recreation via a CAKeyFrameAnimation
- (void) didZoomOrScroll:(float)zoomScale
contentOffset:(CGPoint)scrollViewContentOffset {
CATransform3D scale = CATransform3DMakeScale(zoomScale, zoomScale, 1);
CATransform3D translate = CATransform3DMakeTranslation(-scrollViewContentOffset.x,
-scrollViewContentOffset.y, 0);
CATransform3D concat = CATransform3DConcat(scale, translate);
// _zoomScrollTransforms and _zoomScrollTimes below are of type NSMutableArray
[_zoomScrollTransforms addObject:[NSValue valueWithCATransform3D:concat]];
// secondsElapsed below keeps track of time
[_zoomScrollTimes addObject:[NSNumber numberWithFloat:secondsElapsed]];
}
// Construct layer animation
- (void) constructLayerWithAnimation:(CALayer *)layer {
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
animation.duration = 5.0;
animation.values = _zoomScrollTransforms;
// Adjust key frame times to contain fractional durations
NSMutableArray *keyTimes = [[NSMutableArray alloc] init];
for(int i = 0; i < [_zoomScrollTimes count]; i++) {
NSNumber *number = (NSNumber *)[_zoomScrollTimes objectAtIndex:i];
NSNumber *fractionalDuration = [NSNumber numberWithFloat:[number floatValue]/animation.duration];
[keyTimes addObject:fractionalDuration];
}
animation.keyTimes = keyTimes;
animation.removedOnCompletion = YES;
animation.beginTime = 0;
animation.calculationMode = kCAAnimationDiscrete;
animation.fillMode = kCAFillModeForwards;
[layer addAnimation:animation forKey:nil];
}
當上述層是動畫,其內容被適當地縮放,但它被不正確地定位。內容似乎是x
和y
,移位超出我的預期,因此不會完全回溯用戶在UIScrollView上完成的縮放/平鋪。
任何想法我可能做錯了什麼?
答案
好吧,我想清楚我做錯了什麼。它必須與CALayer的錨點有關。 CALayers上的轉換始終應用於定位點。對於CALayers,默認情況下,定位點爲(0.5,0.5)。因此正在沿着中心點進行縮放和翻譯。另一方面,UIScrollViews從視圖的左上角給出偏移量。基本上,您可以考慮UIScrollView的錨點,以便考慮CGPoint偏移值,爲(0.0,0.0)。
所以解決方法是將CALayer的錨點設置爲(0.0,0.0)。然後一切按預期工作。
還有其他資源以更好的方式呈現此信息。看到這個在Stackoverflow上的另一個問題是similar。另請參閱蘋果文檔中的this article,該文檔詳細討論幾何中的位置,定位點和常規層。
謝謝@mak。我在提交帖子之前嘗試過。我再次嘗試了它,並且比'CATransform3DConcat(scale,translate)'更加替代它。它不幸的工作。 – krissb