单个视图上的多个投影效果(iOS)

13
我想在一个视图中添加多个具有不同透明度的投影效果。阴影的规格如下:
- Y轴偏移量为4,模糊半径为1 - Y轴偏移量为10,模糊半径为10 - Y轴偏移量为2,模糊半径为4 - 模糊半径为1,扩散程度为1(没有偏移,可能需要使用4个不同的阴影)
我可以使用CALayer轻松实现所有这些内容。这是我已经可以工作的代码(请注意,我还没有设置shadowPath,并且在实现多个阴影之前不会设置):
layer.cornerRadius = 4
layer.masksToBounds = false
layer.shouldRasterize = true
let layer2 = CALayer(layer: layer), layer3 = CALayer(layer: layer), layer4 = CALayer(layer: layer)
layer.shadowOffset = CGSizeMake(0, 4)
layer.shadowRadius = 1
layer2.shadowOffset = CGSizeMake(0, 10)
layer2.shadowRadius = 10
layer2.shadowColor = UIColor.blackColor().CGColor
layer2.shouldRasterize = true //Evidently not copied during initialization from self.layer
layer3.shadowOffset = CGSizeMake(0, 2)
layer3.shadowRadius = 4
layer3.shouldRasterize = true
layer4.shadowOffset = CGSizeMake(0, 1)
layer4.shadowRadius = 1
layer4.shadowOpacity = 0.1
layer4.shouldRasterize = true
layer.addSublayer(layer2)
layer.addSublayer(layer3)
layer.addSublayer(layer4)

虽然这段代码是用Swift编写的,但我相信大多数Cocoa/Objective-C开发人员看起来都很熟悉。只要知道在此上下文中,layer等同于self.layer即可。

然而,当我尝试为每个阴影使用不同的不透明度时,问题就出现了。layershadowOpacity属性最终被应用到了所有子层上。这是一个问题,因为我需要它们每个人都有自己的阴影不透明度。我已经尝试将每个层的阴影不透明度设置为其正确值(0.040.12等),但是然后layer0.04不透明度会被应用到所有子层。所以我尝试将layer.shadowOpacity设置为1.0,但这使得所有的阴影都变成了实心黑色。我也试图聪明地做layer2.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.12).CGColor,但它只是变成了完全不透明的黑色。

我想这样做也许有些道理,即所有图层都应该具有相同的阴影不透明度。但有什么办法可以让这个工作起来,同时又具有可变的不透明度等(如果使用CALayer不是很容易的话)?

请不要回答"只需使用图像":无论它看起来多么合理,我想避免这样做。帮我解决这个问题。

谢谢。

编辑:根据请求,这就是我想要的:Goal


你能否发布一张你的视图截图,这样我就能了解你试图做什么,然后或许可以帮助你。 - artud2000
@artud2000,我添加了一张图片来展示我想要实现的内容。 - Aehmlo
@artud2000 不是的,这相当于[[CALayer alloc] initWithLayer: layer],根据苹果文档,它返回“一个图层实例,其中包含从图层复制的任何自定义实例变量”——属性似乎被复制了。 - Aehmlo
你最终让它工作了吗? - tettoffensive
@tettoffensive 不好意思,这个项目基本上已经被搁置了。不过如果你找到解决方法的话,请分享一下! - Aehmlo
显示剩余5条评论
2个回答

4
需要添加的关键是设置层的shadowPath。 默认情况下,Core Graphics 在图层可见内容周围绘制阴影,但在您的代码中,既未为图层设置backgroundColor也未设置bounds,因此图层实际上为空。

假设您有一个UIView子类,可以通过添加类似以下内容来使其正常工作:

override func layoutSubviews() {
    super.layoutSubviews()
    layer.sublayers?.forEach { (sublayer) in
        sublayer.shadowPath = UIBezierPath(rect: bounds).cgPath
    }
}

我在一个带有多重阴影的视图上测试了这种方法,并且当对阴影层定义shadowPath时,它按预期工作。不同的阴影颜色和透明度也可以工作,但您必须记住层次结构中的上层将覆盖其后面的层,因此如果前面的层具有浓密的阴影,则其他阴影可能会被隐藏。


-1

关于在阴影颜色中添加 alpha 而不是图层阴影不透明度的想法如何?

即,而不是

layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 0.5

layer.shadowColor = UIColor.black.withAlphaComponent(0.5).cgColor

对于每一层。


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