40

给定iOS上的任意UIView,有没有办法使用Core Graphics(想到CAGradientLayer)对其应用“前景透明”渐变?

我不能使用标准的 CAGradientLayer,因为背景比 UIColor 更复杂。我也不能覆盖 PNG,因为当我的子视图沿其父垂直滚动视图滚动时,背景会发生变化(见图)。

我有一个不优雅的后备:让我的 uiview 剪辑它的子视图,并在滚动父滚动视图时移动背景的预渲染渐变 png。

透明uiview渐变问题

4

5 回答 5

98

这是一个令人尴尬的简单修复:应用 CAGradientLayer 作为我的子视图的蒙版。

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = _fileTypeScrollView.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:(id)[UIColor whiteColor].CGColor, (id)[UIColor clearColor].CGColor, nil];
gradientLayer.startPoint = CGPointMake(0.8f, 1.0f);
gradientLayer.endPoint = CGPointMake(1.0f, 1.0f);
_fileTypeScrollView.layer.mask = gradientLayer;

感谢Cocoanetics为我指明了正确的方向!

于 2012-06-01T18:17:58.830 回答
10

这就是我要做的。

第 1 步定义自定义渐变视图(Swift 4):

import UIKit

class GradientView: UIView {
    override open class var layerClass: AnyClass {
        return CAGradientLayer.classForCoder()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        let gradientLayer = self.layer as! CAGradientLayer
        gradientLayer.colors = [
            UIColor.white.cgColor,
            UIColor.init(white: 1, alpha: 0).cgColor
        ]
        backgroundColor = UIColor.clear
    }
}

第 2 步- 在情节提要中拖放 aUIView并将其自定义类设置为GradientView

在此处输入图像描述

例如,上面的渐变视图如下所示:


https://github.com/yzhong52/GradientViewDemo

于 2017-06-09T19:19:28.883 回答
2

渐变示例

我刚遇到同样的问题,最后写了自己的课。这似乎是严重的矫枉过正,但这是我能找到的唯一方法来做透明的渐变。你可以在这里看到我的文章和代码示例

它基本上归结为创建两个图像的自定义 UIView。一种是纯色,另一种是用作图像蒙版的渐变色。从那里我将生成的图像应用到 uiview.layer.content。

我希望它有帮助,乔

于 2012-10-20T07:16:07.593 回答
2

我使用了上面接受的(OP's)答案并遇到了评论中提到的相同问题- 当视图滚动时,从屏幕开始的所有内容现在都是透明的,被面具覆盖。

解决方案是将渐变层添加为superview的掩码,而不是scroll view的掩码。就我而言,我使用的是一个文本视图,它包含在一个名为contentView.

我添加了第三种颜色并使用 and代替locations,因此文本视图下方的项目仍然可见。startPointendPoint

let gradientLayer = CAGradientLayer()
gradientLayer.frame = self.contentView!.bounds
gradientLayer.colors = [UIColor.white.cgColor, UIColor.clear.cgColor, UIColor.white.cgColor]

// choose position for gradient, aligned to bottom of text view
let bottomOffset = (self.textView!.frame.size.height + self.textView!.frame.origin.y + 5)/self.contentView!.bounds.size.height
let topOffset = bottomOffset - 0.1
let bottomCoordinate = NSNumber(value: Double(bottomOffset))
let topCoordinate = NSNumber(value: Double(topOffset))
gradientLayer.locations = [topCoordinate, bottomCoordinate, bottomCoordinate]

self.contentView!.layer.mask = gradientLayer

以前,在屏幕外开始的文本是永久不可见的。通过我的修改,滚动按预期工作,并且“关闭”按钮没有被遮罩覆盖。

截屏

于 2018-11-14T19:27:53.237 回答
0

我不想这么说,但我认为你进入了 CUSTOM UIView 领域。我认为我会尝试在覆盖 drawRect 例程的自定义 UIView 中实现这一点。

有了这个,您可以拥有该视图,放置在您的实际滚动视图之上,并让您的渐变视图(如果您愿意)“传递”所有触摸事件(即放弃第一响应者)。

于 2012-06-01T16:00:54.940 回答