我试图在UIScrollView
上生成一些具有相当复杂层次结构的渐弱边缘,其长度可以在滚动时轻松调整。这基本上就是我想要达到的效果(注意渐弱的边缘):
棘手的部分是:
contentOffset
的增加,渐弱效果会增加我使用自定义CAGradientLayer
得到了我想要的大部分内容mask
,它被用作视图层的CAGradientLayer
,但问题是它在性能方面不够好。然后我尝试按需切换掩码,即。滚动开始时,将设置遮罩,当滚动停止时,将移除遮罩。这种工作(有一些错误),但我后来发现,动态更改掩码有不确定的行为,根据Apple文档。我还没有确定一个基于CoreGraphics的解决方案,我不确定它是否可行或性能是否会更好。我也无法使用图像来模拟渐变,因为内容和背景都是动态的。
这是我创建的自定义- (id) init {
self = [super init];
if (self) {
self.anchorPoint = CGPointZero;
self.startPoint = CGPointMake(0.0, 0.5);
self.endPoint = CGPointMake(1.0, 0.5);
CGColorRef transluscentColor = [UIColor colorWithWhite:1.0 alpha:0.0].CGColor;
CGColorRef opaqueColor = [UIColor colorWithWhite:1.0 alpha:1.0].CGColor;
self.colors = [NSArray arrayWithObjects:
(id)opaqueColor,
(id)transluscentColor,
(id)opaqueColor,
(id)opaqueColor,
(id)transluscentColor,
(id)opaqueColor, nil];
self.locations = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:1.0f],
[NSNumber numberWithFloat:1.0f],
[NSNumber numberWithFloat:1.0f], nil];
}
return self;
}
- (void) setAbsoluteStartPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint {
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.startPoint = CGPointMake(startPoint.x / self.bounds.size.width, startPoint.y / self.bounds.size.height);
self.endPoint = CGPointMake(endPoint.x / self.bounds.size.width, endPoint.y / self.bounds.size.height);
[CATransaction commit];
}
- (void) setGradientStartLength:(CGFloat)startLength endLength:(CGFloat)endLength animated:(BOOL)animated {
CGFloat deltaX = (self.endPoint.x - self.startPoint.x);
CGFloat deltaY = (self.endPoint.y - self.startPoint.y);
// use the side whose change is largest as our base length
CGFloat sideLength = (deltaX > deltaY ? self.bounds.size.width * deltaX : self.bounds.size.height * deltaY);
CGFloat startRatio = MAX((startLength / sideLength), 0.0f);
CGFloat endRatio = 1.0f - MAX((endLength / sideLength), 0.0f);
NSArray *locations = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:startRatio],
[NSNumber numberWithFloat:endRatio],
[NSNumber numberWithFloat:1.0f],
[NSNumber numberWithFloat:1.0f], nil];
[CATransaction begin];
if (animated) {
[CATransaction setAnimationDuration:0.5];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
}
else {
[CATransaction setDisableActions:YES];
}
self.locations = locations;
[CATransaction commit];
}
子类的实现:
UIScrollView
与我的position
一起使用时,我基本上只是调整图层的contentOffset
以匹配setGradientStartLength:endLength:animated:
,然后使用mask
调整大小而不使用动画(动画不会)虽然减慢了很多事情。)
就像我说的,这将做我想要的,但不是我所需要的性能水平(帧率从60fps下降到30左右,用作滚动视图的mask
)。在没有使用mask
属性的情况下,我还没有想出一个很好的方法,我认为这是我必须这样做的方式。
我的猜测是,这可以使用与上面类似的代码实现,但使用我的图层作为子图层而不是视图的{{1}}。但是当我将这个图层用作子图层时,我还没有确定如何添加这样的淡入淡出效果,而且我还没有看到任何其他人做过同样的例子。
有人能指出我在正确的方向吗?我发现Apple关于这些事情的文档非常有限。