我的应用程序中有一个UIScrollView,我在其他一些应用程序中看到,当用户滚动时,顶部会在滚动时淡出而不是仅仅消失。
我真的很喜欢这种效果并希望实现它。有什么想法可以做到吗?
答案 0 :(得分:14)
编辑:我已将此代码放在github上,请参阅here。
请参阅my answer类似的问题。
我的解决方案是子类UIScrollView
,并在layoutSubviews
方法中创建一个遮罩层。
#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];
答案 1 :(得分:14)
根据Rob的好回答,这里是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 ...
(很明显,网页视图本身是白色;网页视图恰好位于灰色背景上。因此,fadeTail功能基本上淡出了&#34;整个&#34;网络视图,以及下面发生的任何事情。)
希望能节省一些人打字,欢呼
答案 2 :(得分:8)
您可以使用CAGradientLayer
将QuartzCore.framework添加到项目中(参见Linking to Library or Framework)。
添加QuartzCore标题的#import
:
#import <QuartzCore/QuartzCore.h>
然后使用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
是从alpha为0.0(例如clearColor
)到颜色的颜色到alpha为1.0的颜色(例如whiteColor
)的渐变,而不仅仅是从黑色到白色。您可以调整startPoint
(默认值可能很好)和endPoint
来调整您希望应用渐变的位置。
通常,使用UIScrollView
执行此操作时,除非您希望渐变与您一起滚动,否则将UIScrollView
设为其他UIView
的子视图并将此渐变应用于容器视图,而不是滚动视图本身。
答案 3 :(得分:2)
您可以将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”是定义遮罩区域的灰度图像:白色==完全蒙版,黑色==完全没有蒙版,灰色==部分蒙版。
要创建您正在寻找的效果,蒙版图像将为黑色,顶部带有白色渐变,如下所示:
有关详细信息,请查看CGImageMaskCreate
的文档。
答案 4 :(得分:2)
感谢Fattie的回答,我在swift中创建了以下UIView扩展,它可以处理渐变衰落并提供更多样式(底部,顶部,左侧,垂直和水平)
扩展名:
extension UIView {
enum UIViewFadeStyle {
case bottom
case top
case left
case right
case vertical
case horizontal
}
func fadeView(style: UIViewFadeStyle = .bottom, percentage: Double = 0.07) {
let gradient = CAGradientLayer()
gradient.frame = bounds
gradient.colors = [UIColor.white.cgColor, UIColor.clear.cgColor]
let startLocation = percentage
let endLocation = 1 - percentage
switch style {
case .bottom:
gradient.startPoint = CGPoint(x: 0.5, y: endLocation)
gradient.endPoint = CGPoint(x: 0.5, y: 1)
case .top:
gradient.startPoint = CGPoint(x: 0.5, y: startLocation)
gradient.endPoint = CGPoint(x: 0.5, y: 0.0)
case .vertical:
gradient.startPoint = CGPoint(x: 0.5, y: 0.0)
gradient.endPoint = CGPoint(x: 0.5, y: 1.0)
gradient.colors = [UIColor.clear.cgColor, UIColor.white.cgColor, UIColor.white.cgColor, UIColor.clear.cgColor]
gradient.locations = [0.0, startLocation, endLocation, 1.0] as [NSNumber]
case .left:
gradient.startPoint = CGPoint(x: startLocation, y: 0.5)
gradient.endPoint = CGPoint(x: 0.0, y: 0.5)
case .right:
gradient.startPoint = CGPoint(x: endLocation, y: 0.5)
gradient.endPoint = CGPoint(x: 1, y: 0.5)
case .horizontal:
gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
gradient.endPoint = CGPoint(x: 1.0, y: 0.5)
gradient.colors = [UIColor.clear.cgColor, UIColor.white.cgColor, UIColor.white.cgColor, UIColor.clear.cgColor]
gradient.locations = [0.0, startLocation, endLocation, 1.0] as [NSNumber]
}
layer.mask = gradient
}
}
如有任何意见/建议,请通过gist I've created.
告知我们答案 5 :(得分:1)
我们建立了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