[英]UIView transparent gradient
Given an arbitrary UIView on iOS, is there a way using Core Graphics (CAGradientLayer comes to mind) to apply a "foreground-transparent" gradient to it? 给定iOS上的任意UIView,是否可以使用Core Graphics(想到CAGradientLayer)对其应用“前景透明”渐变?
I can't use a standard CAGradientLayer because the background is more complex than a UIColor. 我不能使用标准的CAGradientLayer,因为背景比UIColor更复杂。 I also can't overlay a PNG because the background will change as my subview is scrolled along its parent vertical scrollview (see image).
我也无法覆盖PNG,因为当子视图沿其父垂直滚动视图滚动时,背景将发生变化(参见图片)。
I have a non-elegant fallback: have my uiview clip its subviews and move a pre-rendered gradient png of the background as the parent scrollview is scrolled. 我有一个非优雅的回退:让我的uiview剪辑其子视图,并在滚动父滚动视图时移动背景的预渲染渐变png。
This was an embarrassingly easy fix: apply a CAGradientLayer as my subview's mask. 这是一个非常尴尬的简单修复:将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;
Thanks to Cocoanetics for pointing me in the right direction! 感谢Cocoanetics向我指出正确的方向!
This is how I'll do. 这就是我要做的。
Step 1 Define a custom gradient view (Swift 4): 步骤1定义自定义渐变视图(快速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
}
}
Step 2 - Drag and drop a UIView
in your storyboard and set its custom class to GradientView
第2步 -将
UIView
拖放到情节UIView
中,并将其自定义类设置为GradientView
As an example, this is how the above gradient view looks like: 例如,上面的渐变视图如下所示:
https://github.com/yzhong52/GradientViewDemo https://github.com/yzhong52/GradientViewDemo
I just ran into the same issue and wound up writing my own class. 我只是遇到了同样的问题,最后写了自己的课。 It seems like serious overkill, but it was the only way I could find to do gradients with transparency.
这似乎严重过头了,但这是我发现透明化渐变的唯一方法。 You can see my writeup and code example here
您可以在这里看到我的文章和代码示例
It basically comes down to a custom UIView that creates two images. 基本上,它归结为创建两个图像的自定义UIView。 One is a solid color, the other is a gradient that is used as an image mask.
一种是纯色,另一种是用作图像蒙版的渐变。 From there I applied the resulting image to the uiview.layer.content.
从那里,我将生成的图像应用于uiview.layer.content。
I hope it helps, Joe 我希望能帮上忙,乔
I used the accepted (OP's) answer above and ran into the same issue noted in an upvoted comment - when the view scrolls, everything that started offscreen is now transparent, covered by the mask. 我使用了上面接受的(OP)答案,并遇到了同一问题, 该问题已在经投票赞成的注释中显示 -当视图滚动时,屏幕外开始的所有内容现在都是透明的,被蒙版覆盖。
The solution was to add the gradient layer as the superview 's mask, not the scroll view 's mask. 解决方案是将渐变层添加为超级视图的蒙版,而不是滚动视图的蒙版。 In my case, I'm using a text view, which is contained inside a view called
contentView
. 就我而言,我使用的是文本视图,该视图包含在名为
contentView
的视图内。
I added a third color and used locations
instead of startPoint
and endPoint
, so that items below the text view are still visible. 我添加了第三种颜色,并使用了
locations
而不是startPoint
和endPoint
,以便文本视图下方的项目仍然可见。
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
Before, the text that started offscreen was permanently invisible. 以前,屏幕外开始的文本是永久不可见的。 With my modifications, scrolling works as expected, and the "Close" button is not covered by the mask.
经过我的修改,滚动按预期进行,并且“关闭”按钮未被遮罩覆盖。
I hate to say it, but I think that you are into the CUSTOM UIView land. 我不想这么说,但是我认为您已经进入CUSTOM UIView领域。 I think that I would try to implement this in a custom UIView overiding the drawRect routine.
我认为我会尝试在覆盖drawRect例程的自定义UIView中实现此功能。
With this, you could have that view, place on top of your actual scrollview, and have your gradient view (if you will) "pass-on" all touch events (ie relinquish first responder). 这样,您就可以拥有该视图,将其放置在实际的滚动视图之上,并让您的渐变视图(如果可以)“传递”所有触摸事件(即放弃第一响应者)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.