如何使用UIScrollView创build最佳淡入淡出效果?

我在我的应用程序中有一个UIScrollView,并且在其他一些应用程序中看到,当用户滚动时,顶部部分在滚动上淡出而不是消失。

我真的很喜欢这个效果,想要达到这个效果。 任何想法如何可以做到?

编辑:我已经把这个代码放在Github,看到这里 。


看到我对类似问题的回答。

我的解决scheme是子类UIScrollView ,并在layoutSubviews方法中创build一个遮罩层。

 #import "FadingScrollView.h" #import <QuartzCore/QuartzCore.h> static float const fadePercentage = 0.2; @implementation FadingScrollView // ... - (void)layoutSubviews { [super layoutSubviews]; NSObject * transparent = (NSObject *) [[UIColor colorWithWhite:0 alpha:0] CGColor]; NSObject * opaque = (NSObject *) [[UIColor colorWithWhite:0 alpha:1] CGColor]; CALayer * maskLayer = [CALayer layer]; maskLayer.frame = self.bounds; CAGradientLayer * gradientLayer = [CAGradientLayer layer]; gradientLayer.frame = CGRectMake(self.bounds.origin.x, 0, self.bounds.size.width, self.bounds.size.height); gradientLayer.colors = [NSArray arrayWithObjects: transparent, opaque, opaque, transparent, nil]; // Set percentage of scrollview that fades at top & bottom gradientLayer.locations = [NSArray arrayWithObjects: [NSNumber numberWithFloat:0], [NSNumber numberWithFloat:fadePercentage], [NSNumber numberWithFloat:1.0 - fadePercentage], [NSNumber numberWithFloat:1], nil]; [maskLayer addSublayer:gradientLayer]; self.layer.mask = maskLayer; } @end 

上面的代码将UIScrollView的顶部和底部从背景颜色淡化为透明,但是可以轻松地将其更改为淡入淡出顶部(或淡入所需的任何颜色)。

改变这一行只能淡出顶部:

 // Fade top of scrollview only gradientLayer.locations = [NSArray arrayWithObjects: [NSNumber numberWithFloat:0], [NSNumber numberWithFloat:fadePercentage], [NSNumber numberWithFloat:1], [NSNumber numberWithFloat:1], nil]; 

编辑2:

或者通过改变这两行来淡化顶端:

 // Fade top of scrollview only gradientLayer.colors = [NSArray arrayWithObjects: transparent, opaque, nil]; gradientLayer.locations = [NSArray arrayWithObjects: [NSNumber numberWithFloat:0], [NSNumber numberWithFloat:fadePercentage], nil]; 

或者,只淡化底部:

 // Fade bottom of scrollview only gradientLayer.colors = [NSArray arrayWithObjects: opaque, transparent, nil]; gradientLayer.locations = [NSArray arrayWithObjects: [NSNumber numberWithFloat:1.0 - fadePercentage], [NSNumber numberWithFloat:1], nil]; 

您可以使用CAGradientLayer

  1. 将QuartzCore.framework添加到您的项目(请参阅链接到库或框架 )。

  2. 添加QuartzCore头文件的#import

     #import <QuartzCore/QuartzCore.h> 
  3. 然后使用CAGradientLayer

     - (void)addGradientMaskToView:(UIView *)view { CAGradientLayer *gradient = [CAGradientLayer layer]; gradient.frame = view.bounds; gradient.colors = @[(id)[[UIColor clearColor] CGColor], (id)[[UIColor whiteColor] CGColor]]; gradient.startPoint = CGPointMake(0.5, 0.0); // this is the default value, so this line is not needed gradient.endPoint = CGPointMake(0.5, 0.20); [view.layer setMask:gradient]; } 

请注意,此CAGradientLayer是从0.0(如clearColor )到alpha的颜色到alpha为1.0(例如whiteColor )的颜色的whiteColor ,而不仅仅是从黑到白。 您可以调整startPoint (默认值可能是罚款)和endPoint来调整您要应用渐变的位置。

一般情况下,当使用UIScrollView进行此操作时,除非您希望渐变与您一起滚动,否则将使UIScrollView成为其他某个UIView的子视图,并将此渐变应用于该容器视图,而不是滚动视图本身。

只是基于罗布的伟大的答案,这是UIView类别,

 @implementation UIView (Looks) -(void)fadeTail { CAGradientLayer *gradient = [CAGradientLayer layer]; gradient.frame = self.bounds; gradient.colors = @[ (id)[[UIColor whiteColor] CGColor], (id)[[UIColor clearColor] CGColor] ]; gradient.startPoint = CGPointMake(0.5, 0.93); gradient.endPoint = CGPointMake(0.5, 1); [self.layer setMask:gradient]; } @end 

这是在这里看到一个小的UIWebView …

在这里输入图像说明

(要清楚的是,Web视图本身是白色的 ,Web视图恰好坐在灰色的背景上,所以fadeTail函数基本上淡出了“整个”Web视图,无论发生什么。

希望它可以节省一些打字的人,欢呼声

你添加一个alpha遮罩层到包含你的滚动视图的视图,如下所示:

 CALayer *mask = [CALayer layer]; CGImageRef maskRef = [UIImage imageNamed:@"scrollMask"].CGImage; CGImageRef maskImage = CGImageMaskCreate(CGImageGetWidth(maskRef), CGImageGetHeight(maskRef), CGImageGetBitsPerComponent(maskRef), CGImageGetBitsPerPixel(maskRef), CGImageGetBytesPerRow(maskRef), CGImageGetDataProvider(maskRef), NULL, false); mask.contents = (__bridge id)maskImage; mask.frame = CGRectMake(0, 0, view.bounds.size.width, view.bounds.size.height); view.layer.mask = mask; view.layer.masksToBounds = YES; CGImageRelease(maskImage); 

其中“scrollMask”是定义遮罩区域的灰度图像:白色==完全遮罩,黑色==完全遮罩,灰色==部分遮罩。

要创build你正在寻找的效果,蒙版图像将是黑色的,顶部有一个白色渐变,如下所示:

在这里输入图像说明

有关更多详细信息,请CGImageMaskCreate的文档。

我们build立在Steph Sharp的代码上,只在必要的时候才淡出。 我们的代码被设置为静态工具方法而不是子类,以便我们可以在UIScrollView和UITableView的子类中重用该方法。 这是我们的静态效用方法:

 #define kScrollViewFadeColorLight [UIColor colorWithRed:0.56 green:0.56 blue:0.56 alpha:0.0] #define kScrollViewFadeColorDark [UIColor colorWithRed:0.56 green:0.56 blue:0.56 alpha:1.0] #define kScrollViewScrollBarWidth 7.0 #define kScrollViewFadingEdgeLength 40.0 + (void) applyFadeToScrollView:(UIScrollView*) scrollView { CGFloat topOffset = -scrollView.contentInset.top; CGFloat bottomOffset = scrollView.contentSize.height + scrollView.contentInset.bottom - scrollView.bounds.size.height; CGFloat distanceFromTop = scrollView.contentOffset.y - topOffset; CGFloat distanceFromBottom = bottomOffset - scrollView.contentOffset.y; BOOL isAtTop = distanceFromTop < 1.0; BOOL isAtBottom = distanceFromBottom < 1.0; if (isAtTop && isAtBottom) { // There is no scrolling to be done here, so don't fade anything! scrollView.layer.mask = nil; return; } NSObject* transparent = (NSObject*)[kScrollViewFadeColorLight CGColor]; NSObject* opaque = (NSObject*)[kScrollViewFadeColorDark CGColor]; CALayer* maskLayer = [CALayer layer]; maskLayer.frame = scrollView.bounds; CALayer* scrollGutterLayer = [CALayer layer]; scrollGutterLayer.frame = CGRectMake(scrollView.bounds.size.width - kScrollViewScrollBarWidth, 0.0, kScrollViewScrollBarWidth, scrollView.bounds.size.height); scrollGutterLayer.backgroundColor = (__bridge CGColorRef)(opaque); [maskLayer addSublayer:scrollGutterLayer]; CAGradientLayer* gradientLayer = [CAGradientLayer layer]; gradientLayer.frame = CGRectMake(0.0, 0.0, scrollView.bounds.size.width, scrollView.bounds.size.height); CGFloat fadePercentage = kScrollViewFadingEdgeLength / scrollView.bounds.size.height; NSMutableArray* colors = [[NSMutableArray alloc] init]; NSMutableArray* locations = [[NSMutableArray alloc] init]; if (!isAtTop) { [colors addObjectsFromArray:@[transparent, opaque]]; [locations addObjectsFromArray:@[@0.0, [NSNumber numberWithFloat:fadePercentage]]]; } if (!isAtBottom) { [colors addObjectsFromArray:@[opaque, transparent]]; [locations addObjectsFromArray:@[[NSNumber numberWithFloat:1.0 - fadePercentage], @1.0]]; } gradientLayer.colors = colors; gradientLayer.locations = locations; [maskLayer addSublayer:gradientLayer]; scrollView.layer.mask = maskLayer; } 

这是我们使用这种方法。

FadingScrollView.h

 @interface FadingScrollView : UIScrollView @end 

FadingScrollView.m

 @implementation FadingScrollView - (void) layoutSubviews { [super layoutSubviews]; [Utils applyFadeToScrollView:self]; } @end 

FadingTableView.h

 @interface FadingTableView : UITableView @end 

FadingTableView.m

 @implementation FadingTableView - (void) layoutSubviews { [super layoutSubviews]; [Utils applyFadeToScrollView:self]; } @end 

视图是滚动视图的所有子视图,因此它们都有自己的alpha 。 您可以充当滚动视图的委托,而在scrollViewDidScroll您可以检查contentOffset并更改所需的任何子视图的alpha