And*_* R. 4 iphone core-animation objective-c ios
我试图动画a的位置,CAGradientLayer以便在UIScrollView达到某个位置时缩小.我将渐变设置为遮罩UIScrollView,并调整渐变的locations属性以在滚动视图滚动时展开一些.这对我来说很好,除非我尝试动画更改位置.当我执行动画时 - 无论是显式CABasicAnimation还是隐式 - 动画都能正确执行,但无论出于何种原因,一旦动画完成,它就会将渐变(无动画)的位置更改为其他非零开始和结束点.它每次使用相同的值来执行此操作,并且在我的代码中的任何位置都未指定这些值.
我对核心动画很新,所以也许我错过了一些东西,但据我所知,我的代码是正确的.我也试过等待执行动画,以解决滚动的任何时间问题,但这也没有帮助.
这是我的代码(相关部分,无论如何):
- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[CATransaction begin];
[CATransaction setDisableActions:YES];
gradientMask.position = CGPointMake(currentPageOffset, 0.0f);
gradientMask.bounds = self.scrollView.bounds;
[CATransaction commit];
_animateGradientShrinkOnScroll = YES;
// Reset scrollView contentOffset (I'm doing infinite paging)
...
}
- (void) scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat offset = self.scrollView.contentOffset.x;
CGFloat relativeOffset = offset - currentPageOffset;
[CATransaction begin];
[CATransaction setDisableActions:YES];
gradientMask.position = self.scrollView.contentOffset;
if (_animateGradientShrinkOnScroll)
[CATransaction commit]; // if animating, set position w/o animation first
CGFloat leftLength = ABS(relativeOffset);
CGFloat rightLength = ABS(relativeOffset);
CGFloat maxLength = [self maxGradientLength];
leftLength = MIN((leftLength / 2), maxLength);
rightLength = MIN((rightLength / 2), maxLength);
// When animating, this effectively always goes from non-zero lengths to zero lengths,
// and I've verified this by logging the values used.
[self setGradientLeftLength:leftLength rightLength:rightLength animated:_animateGradientShrinkOnScroll];
if (!_animateGradientShrinkOnScroll)
[CATransaction commit];
_animateGradientShrinkOnScroll = NO;
}
- (void) setGradientLeftLength:(CGFloat)leftLength rightLength:(CGFloat)rightLength animated:(BOOL)animated {
CGFloat startRatio = MAX((leftLength / gradientMask.bounds.size.width), 0);
CGFloat endRatio = 1.0f - MAX((rightLength / gradientMask.bounds.size.width), 0);
NSArray *locations = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:startRatio],
[NSNumber numberWithFloat:endRatio],
[NSNumber numberWithFloat:1.0f], nil];
if (animated) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"locations"];
animation.toValue = locations;
[gradientMask addAnimation:animation forKey:kGradientMaskAnimationShrink];
}
else
gradientMask.locations = locations;
}
Run Code Online (Sandbox Code Playgroud)
向图层添加动画永远不会更改图层的属性.它只是激活屏幕上图层的外观.从图层中移除动画后,将根据图层的属性重新绘制图层.因此,您需要更改图层的属性,然后应用动画.在你的if陈述中,这样做:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"locations"];
animation.fromValue = gradientMask.locations;
animation.toValue = locations;
gradientMask.locations = locations;
[gradientMask addAnimation:animation forKey:animation.keyPath];
Run Code Online (Sandbox Code Playgroud)
为了更好地理解,请观看WWDC 2011中的"Core Animation Essentials"视频.这非常有帮助.
| 归档时间: |
|
| 查看次数: |
2228 次 |
| 最近记录: |