ios UIView 透明渐变
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10852405/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UIView transparent gradient
提问by jpsim
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. I also can't overlay a PNG because the background will change as my subview is scrolled along its parent vertical scrollview (see image).
我不能使用标准的 CAGradientLayer,因为背景比 UIColor 更复杂。我也无法覆盖 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。
回答by jpsim
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 Cocoaneticsfor pointing me in the right direction!
感谢Cocoanetics为我指明了正确的方向!
回答by Yuchen Zhong
This is how I'll do.
这就是我要做的。
Step 1Define a custom gradient view (Swift 4):
步骤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
}
}
Step 2- Drag and drop a UIView
in your storyboard and set its custom class to GradientView
第 2 步- 将 a 拖放到UIView
故事板中并将其自定义类设置为GradientView
As an example, this is how the above gradient view looks like:
例如,上面的渐变视图如下所示:
回答by jab
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
.
解决方案是将渐变图层添加为superview的蒙版,而不是滚动视图的蒙版。就我而言,我使用的是文本视图,它包含在名为contentView
.
I added a third color and used locations
instead of startPoint
and endPoint
, so that items belowthe 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.
以前,从屏幕外开始的文本是永久不可见的。通过我的修改,滚动按预期工作,并且“关闭”按钮没有被遮罩覆盖。
回答by Joe Andolina
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. 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。一种是纯色,另一种是用作图像蒙版的渐变。从那里我将生成的图像应用于 uiview.layer.content。
I hope it helps, Joe
我希望它有帮助,乔
回答by trumpetlicks
I hate to say it, but I think that you are into the CUSTOM UIView land. I think that I would try to implement this in a custom UIView overiding the drawRect routine.
我不想这么说,但我认为您已经进入了 CUSTOM UIView 领域。我想我会尝试在覆盖 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 (i.e. relinquish first responder).
有了这个,你可以拥有那个视图,放在你的实际滚动视图之上,并让你的渐变视图(如果你愿意)“传递”所有触摸事件(即放弃第一响应者)。