ios 如何控制阴影扩散和模糊?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34269399/
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
How to control shadow spread and blur?
提问by Quantaliinuxite
I have designed UI elements in sketch, and one of them has a shadow with blur 1 and spread 0. I looked at the doc for the views layer property and layer doesnt have anything named spread or blur, or anything equivalent (the only control was merely shadowOpacity) How can control things like blur and spread?
我在草图中设计了 UI 元素,其中一个具有模糊 1 和传播 0 的阴影。我查看了视图图层属性的文档,并且图层没有任何名为传播或模糊的东西,或任何等效的东西(唯一的控件是仅仅是shadowOpacity)如何控制模糊和扩散之类的东西?
EDIT:
编辑:
Here are my settings in Sketch :
And here is what I want my shadow to look like:
这是我在 Sketch 中的设置:
这是我希望我的阴影的样子:
And here is what it looks like at the moment:
Note, you have to click on the picture to actually see the shadow.
My code is as follows:
我的代码如下:
func setupLayer(){
view.layer.cornerRadius = 2
view.layer.shadowColor = Colors.Shadow.CGColor
view.layer.shadowOffset = CGSize(width: 0, height: 1)
view.layer.shadowOpacity = 0.9
view.layer.shadowRadius = 5
}
回答by Senseful
Here's how to apply all 6 Sketch shadow properties to a UIView's layer with near perfect accuracy:
以下是如何以近乎完美的精度将所有 6 个 Sketch 阴影属性应用于 UIView 的图层:
extension CALayer {
func applySketchShadow(
color: UIColor = .black,
alpha: Float = 0.5,
x: CGFloat = 0,
y: CGFloat = 2,
blur: CGFloat = 4,
spread: CGFloat = 0)
{
shadowColor = color.cgColor
shadowOpacity = alpha
shadowOffset = CGSize(width: x, height: y)
shadowRadius = blur / 2.0
if spread == 0 {
shadowPath = nil
} else {
let dx = -spread
let rect = bounds.insetBy(dx: dx, dy: dx)
shadowPath = UIBezierPath(rect: rect).cgPath
}
}
}
Say we want to represent the following:
假设我们要表示以下内容:
You can easily do this via:
您可以通过以下方式轻松做到这一点:
myView.layer.applySketchShadow(
color: .black,
alpha: 0.5,
x: 0,
y: 0,
blur: 4,
spread: 0)
or more succinctly:
或更简洁地说:
myView.layer.applySketchShadow(y: 0)
Example:
例子:
Left: iPhone 8 UIView screenshot; right: Sketch rectangle.
左:iPhone 8 UIView 截图;右:草图矩形。
Note:
笔记:
- When using a non-zero
spread
, it hardcodes a path based on thebounds
of the CALayer. If the layer's bounds ever change, you'd want to call theapplySketchShadow()
method again.
- 当使用非零值时
spread
,它会根据bounds
CALayer 的对路径进行硬编码。如果图层的边界发生变化,您需要applySketchShadow()
再次调用该方法。
回答by O-mkar
You can try this .... you can play with the values.
The shadowRadius
dictates the amount of blur. shadowOffset
dictates where the shadow goes.
你可以试试这个....你可以玩这些值。该shadowRadius
使然模糊量。shadowOffset
决定了阴影的去向。
Swift 2.0
斯威夫特 2.0
let radius: CGFloat = demoView.frame.width / 2.0 //change it to .height if you need spread for height
let shadowPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 2.1 * radius, height: demoView.frame.height))
//Change 2.1 to amount of spread you need and for height replace the code for height
demoView.layer.cornerRadius = 2
demoView.layer.shadowColor = UIColor.blackColor().CGColor
demoView.layer.shadowOffset = CGSize(width: 0.5, height: 0.4) //Here you control x and y
demoView.layer.shadowOpacity = 0.5
demoView.layer.shadowRadius = 5.0 //Here your control your blur
demoView.layer.masksToBounds = false
demoView.layer.shadowPath = shadowPath.CGPath
Swift 3.0
斯威夫特 3.0
let radius: CGFloat = demoView.frame.width / 2.0 //change it to .height if you need spread for height
let shadowPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 2.1 * radius, height: demoView.frame.height))
//Change 2.1 to amount of spread you need and for height replace the code for height
demoView.layer.cornerRadius = 2
demoView.layer.shadowColor = UIColor.black.cgColor
demoView.layer.shadowOffset = CGSize(width: 0.5, height: 0.4) //Here you control x and y
demoView.layer.shadowOpacity = 0.5
demoView.layer.shadowRadius = 5.0 //Here your control your blur
demoView.layer.masksToBounds = false
demoView.layer.shadowPath = shadowPath.cgPath
Example with spread
传播示例
To create a basic shadow
创建基本阴影
demoView.layer.cornerRadius = 2
demoView.layer.shadowColor = UIColor.blackColor().CGColor
demoView.layer.shadowOffset = CGSizeMake(0.5, 4.0); //Here your control your spread
demoView.layer.shadowOpacity = 0.5
demoView.layer.shadowRadius = 5.0 //Here your control your blur
Basic Shadow example in Swift 2.0
Swift 2.0 中的基本阴影示例
回答by O-mkar
Sketch Shadow Using IBDesignable and IBInspectable in Swift 4
在 Swift 4 中使用 IBDesignable 和 IBInspectable 绘制阴影
SKETCH AND XCODE SIDE BY SIDE
草图和 Xcode 并排
CODE
代码
@IBDesignable class ShadowView: UIView {
@IBInspectable var shadowColor: UIColor? {
get {
if let color = layer.shadowColor {
return UIColor(cgColor: color)
}
return nil
}
set {
if let color = newValue {
layer.shadowColor = color.cgColor
} else {
layer.shadowColor = nil
}
}
}
@IBInspectable var shadowOpacity: Float {
get {
return layer.shadowOpacity
}
set {
layer.shadowOpacity = newValue
}
}
@IBInspectable var shadowOffset: CGPoint {
get {
return CGPoint(x: layer.shadowOffset.width, y:layer.shadowOffset.height)
}
set {
layer.shadowOffset = CGSize(width: newValue.x, height: newValue.y)
}
}
@IBInspectable var shadowBlur: CGFloat {
get {
return layer.shadowRadius
}
set {
layer.shadowRadius = newValue / 2.0
}
}
@IBInspectable var shadowSpread: CGFloat = 0 {
didSet {
if shadowSpread == 0 {
layer.shadowPath = nil
} else {
let dx = -shadowSpread
let rect = bounds.insetBy(dx: dx, dy: dx)
layer.shadowPath = UIBezierPath(rect: rect).cgPath
}
}
}
}
OUTPUT
输出
HOW TO USE IT
如何使用它
回答by Cesare
This code worked very well for me:
这段代码对我来说效果很好:
yourView.layer.shadowOpacity = 0.2 // opacity, 20%
yourView.layer.shadowColor = UIColor.black.cgColor
yourView.layer.shadowRadius = 2 // HALF of blur
yourView.layer.shadowOffset = CGSize(width: 0, height: 2) // Spread x, y
yourView.layer.masksToBounds = false
回答by Zig
For those who are attempting to apply a shadow to a predefined path (Like for a circular view, for instance), here's what I ended up with:
对于那些试图将阴影应用于预定义路径的人(例如圆形视图),这就是我最终得到的结果:
extension CALayer {
func applyShadow(color: UIColor = .black,
alpha: Float = 0.5,
x: CGFloat = 0,
y: CGFloat = 2,
blur: CGFloat = 4,
spread: CGFloat = 0,
path: UIBezierPath? = nil) {
shadowColor = color.cgColor
shadowOpacity = alpha
shadowRadius = blur / 2
if let path = path {
if spread == 0 {
shadowOffset = CGSize(width: x, height: y)
} else {
let scaleX = (path.bounds.width + (spread * 2)) / path.bounds.width
let scaleY = (path.bounds.height + (spread * 2)) / path.bounds.height
path.apply(CGAffineTransform(translationX: x + -spread, y: y + -spread).scaledBy(x: scaleX, y: scaleY))
shadowPath = path.cgPath
}
} else {
shadowOffset = CGSize(width: x, height: y)
if spread == 0 {
shadowPath = nil
} else {
let dx = -spread
let rect = bounds.insetBy(dx: dx, dy: dx)
shadowPath = UIBezierPath(rect: rect).cgPath
}
}
shouldRasterize = true
rasterizationScale = UIScreen.main.scale
}
}
I'll post some examples later, but this has worked spot on for circular views for me.
我稍后会发布一些示例,但这对我来说适用于循环视图。
回答by Josep Escobar
My solution based on this post replies: (Swift 3)
我基于此帖子回复的解决方案:(Swift 3)
let shadowPath = UIBezierPath(rect: CGRect(x: -1,
y: -2,
width: target.frame.width + 2,
height: target.frame.height + 2))
target.layer.shadowColor = UIColor(hexString: shadowColor).cgColor
target.layer.shadowOffset = CGSize(width: CGFloat(shadowOffsetX), height: CGFloat(shadowOffsetY))
target.layer.masksToBounds = false
target.layer.shadowOpacity = Float(shadowOpacity)
target.layer.shadowPath = shadowPath.cgPath
回答by Piotr Gaw?owski
It might be a little diggin in history, but maybe some had same issue. I useed code sample from accepted answer. However the effects are quite different: - y value has to be around half compared to same value in sketch - I tried to apply shadow on navigation bar and the effect is terribly different - barely visible while using same values that sketch had.
这可能是对历史的一点挖掘,但也许有些人有同样的问题。我使用了接受答案中的代码示例。然而,效果却大不相同: - 与草图中的相同值相比,y 值必须约为一半 - 我尝试在导航栏上应用阴影,但效果非常不同 - 在使用草图具有的相同值时几乎不可见。
So there seems that the method is totally not reflecting sketch parameters. Any hints?
因此,该方法似乎完全没有反映草图参数。任何提示?