gpt4 book ai didi

iphone - 完成后重置 UIScrollView 掩码中的 CAGradientLayer 位置属性动画

转载 作者:可可西里 更新时间:2023-11-01 05:14:51 24 4
gpt4 key购买 nike

我正在尝试为 CAGradientLayer 的位置设置动画,以便在 UIScrollView 到达特定位置时收缩。我将我的渐变设置为 UIScrollView 的掩码,并调整渐变的 locations 属性以在 ScrollView 滚动时扩展一点。这对我来说很好用,除非我试图为位置的变化设置动画。当我执行动画时 - 无论是作为显式 CABasicAnimation 还是隐式 - 动画都能正确执行,但无论出于何种原因,一旦动画完成,它就会将渐变(无动画)的位置更改为一些其他非零起点和终点。它每次都使用相同的值来执行此操作,并且我的代码中的任何地方都没有指定这些值。

我是 Core Animation 的新手,所以也许我遗漏了一些东西,但据我所知我的代码是正确的。我也尝试过等待执行动画,以解决滚动的任何时间问题,但这也没有帮助。

这是我的代码(无论如何都是相关部分):

- (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;
}

最佳答案

向图层添加动画不会更改图层的属性。它只是动画图层在屏幕上的外观。一旦动画从图层中移除,图层就会根据其属性重新绘制。所以你需要改变图层的属性,然后应用动画。在您的 if 语句中,执行以下操作:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"locations"];
animation.fromValue = gradientMask.locations;
animation.toValue = locations;
gradientMask.locations = locations;
[gradientMask addAnimation:animation forKey:animation.keyPath];

为了更好地理解,请观看来自 WWDC 2011 的“核心动画要点”视频.这非常有帮助。

关于iphone - 完成后重置 UIScrollView 掩码中的 CAGradientLayer 位置属性动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11068631/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com