UIScrollView上的高性能,可变长度渐变边缘

时间:2012-07-06 01:39:09

标签: iphone objective-c ios core-animation core-graphics

我试图在UIScrollView上生成一些具有相当复杂层次结构的渐弱边缘,其长度可以在滚动时轻松调整。这基本上就是我想要达到的效果(注意渐弱的边缘):

enter image description here

棘手的部分是:

  1. 背景是动态的事实
  2. 当用户滚动时,我希望渐弱的边缘“增长”;也就是说,当没有发生滚动时它们不存在,但是一旦滚动开始,随着contentOffset的增加,渐弱效果会增加
  3. 与no相似。 2,滚动完成后,渐弱边缘应平滑收缩
  4. 我使用自定义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关于这些事情的文档非常有限。

0 个答案:

没有答案