淡化任何接近UIScollView边缘的内容

11
如标题所述,我试图为一些UIImageViews添加淡出效果,当它们越靠近UIScrollView的四个边缘时。由于用户可以拖动UIImages,如果他将它们拖向边缘,它们开始淡出,而不是给出像UIScrollView有边框的剪切效果。我尝试了这篇教程:http://www.cocoanetics.com/2011/08/adding-fading-gradients-to-uitableview/,这是在另一个堆栈溢出问题中建议的,但它只能应用于UITableViews。我希望图片在距离边框一厘米处开始淡出。

为什么它在UITableView中不能工作? - Undo
3个回答

19

就像你链接到的Cocoanetics文章中所做的那样,你可以创建一个CAGradientLayer来覆盖你的滚动视图。使用你的滚动视图的背景颜色(在我的示例中是白色),使其向左、右、上和下边缘渐隐:

   CGColorRef innerColor = [UIColor colorWithWhite:1.0 alpha:0.0].CGColor;
   CGColorRef outerColor = [UIColor colorWithWhite:1.0 alpha:1.0].CGColor;

   // first, define a horizontal gradient (left/right edges)
   CAGradientLayer* hMaskLayer = [CAGradientLayer layer];
   hMaskLayer.opacity = .7;
   hMaskLayer.colors = [NSArray arrayWithObjects:(id)outerColor,
                        (id)innerColor, (id)innerColor, (id)outerColor, nil];
   hMaskLayer.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],
                           [NSNumber numberWithFloat:0.15],
                           [NSNumber numberWithFloat:0.85],
                           [NSNumber numberWithFloat:1.0], nil];
   hMaskLayer.startPoint = CGPointMake(0, 0.5);
   hMaskLayer.endPoint = CGPointMake(1.0, 0.5);
   hMaskLayer.bounds = self.scrollView.bounds;
   hMaskLayer.anchorPoint = CGPointZero;

   CAGradientLayer* vMaskLayer = [CAGradientLayer layer];
   // without specifying startPoint and endPoint, we get a vertical gradient
   vMaskLayer.opacity = hMaskLayer.opacity;
   vMaskLayer.colors = hMaskLayer.colors;
   vMaskLayer.locations = hMaskLayer.locations;
   vMaskLayer.bounds = self.scrollView.bounds;
   vMaskLayer.anchorPoint = CGPointZero;

   // you must add the masks to the root view, not the scrollView, otherwise
   //  the masks will move as the user scrolls!
   [self.view.layer addSublayer: hMaskLayer];
   [self.view.layer addSublayer: vMaskLayer];
免责声明:这会在四个角落的渐变/淡出效果上有所重叠。您可以查看结果,决定它们是否足够好。如果不行,您也可以尝试在像Photoshop这样的软件中绘制透明图像,并添加一个UIImageView子视图作为蒙版,在其上使用您绘制的图像。

输入图片描述

Youtube 屏幕截图


这是整个scrollView的静态封面还是动态可见矩形? - sangony
这是一个静态的封面,但它被添加到根视图而不是滚动视图本身。您不希望封面实际上随内容一起滚动。或者,通过“动态”,您是否在询问封面是否从开始隐藏,然后在滚动开始后动态出现?不,它不会这样做。我没有在问题描述中看到这一点,并认为这样可能看起来很奇怪。 - Nate
动态指的是如果scrollView的内容大小为2000x2000,模糊效果会出现在2000x2000的边缘还是随着用户移动可见区域而动态地出现在可见区域内部? - sangony
这个解决方案与内容大小无关,只关心屏幕上可见的元素而不是超出屏幕的元素。所以淡入淡出效果应用在可见区域的边缘。它被添加到不移动的根view中,因此它不必担心滚动视图的哪一部分是可见的。它实际上并没有对滚动视图做任何事情。一个透明的渐变,与背景颜色相同,被应用于上面的滚动视图,使其看起来就像内容在边缘处淡化。你是否以不同的方式阅读了问题? - Nate
完全不是。您编写了一些非常优雅的代码,我想确认我认为您所做的事情(现在太懒得尝试您的代码)。 - sangony
1
我看你现在有点懒,那我就送上一个 YouTube 屏幕录像。视频显然比一千个字还要有说服力 :) - Nate

5

以下是 Nate 回答的 Swift 版本,仅适用于顶部和底部:

        let innerColor = UIColor(white: 1.0, alpha: 0.0).CGColor
        let outerColor = UIColor(white: 1.0, alpha: 1.0).CGColor;

        // define a vertical gradient (up/bottom edges)
        let colors = [outerColor, innerColor,innerColor,outerColor]
        let locations = [0.0, 0.15,0.85,1.0]

        var vMaskLayer : CAGradientLayer = CAGradientLayer()// layer];
        // without specifying startPoint and endPoint, we get a vertical gradient
        vMaskLayer.opacity = 0.7
        vMaskLayer.colors = colors;
        vMaskLayer.locations = locations;
        vMaskLayer.bounds = self.scrollView.bounds;
        vMaskLayer.anchorPoint = CGPointZero;

        // you must add the mask to the root view, not the scrollView, otherwise
        //  the masks will move as the user scrolls!
        self.view.layer.addSublayer(vMaskLayer)

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接