单视图 iOS 上的多个投影

Posted

技术标签:

【中文标题】单视图 iOS 上的多个投影【英文标题】:Multiple Drop Shadows on Single View iOS 【发布时间】:2014-08-12 03:39:21 【问题描述】:

我希望在视图中添加多个具有不同不透明度的阴影。阴影的规格如下:

Y 偏移量为 4,模糊半径为 1 Y 偏移为 10,模糊半径为 10 Y 偏移量为 2,模糊半径为 4 模糊半径为 1,散布为 1(无偏移,可能必须是 4 个不同的阴影)

我可以使用CALayers 让所有这些工作正常。这是我为此工作的代码(请注意,我还没有费心设置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)?

请不要回答“只使用图片”:无论这多么理智,我都在努力避免它。快来逗我吧。

谢谢。

编辑:根据要求,这是我所追求的:。

【问题讨论】:

您能否发布您的视图的屏幕截图,以便我了解您想要做什么,我可能会帮助您 @artud2000 添加了我想要实现的目标的图像。 好的,让我看看我们能做什么 Mmmmm 我不熟悉 Swift 但是让 layer2 = CALayer(layer: layer) 那行意味着 layer2 等于 layer?如果是这样,你应该初始化全新的 CALayer 实例,如果不是,如果你改变层中的一个属性,它会影响其他层 @artud2000 不,这相当于 [[CALayer alloc] initWithLayer: layer],根据 Apple 的文档,它返回“具有从层复制的任何自定义实例变量的层实例”——属性好像被抄袭了。 【参考方案1】:

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

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

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

我在具有多个阴影的视图上测试了这种方法,只要为阴影层定义了shadowPath,它就可以按预期工作。不同的阴影颜色和不透明度也可以,但您必须记住,层次结构中的上层会与它们后面的层重叠,因此如果前层有较厚的阴影,其他阴影可能会被它隐藏。

【讨论】:

【参考方案2】:

如何将 alpha 添加到阴影颜色而不是图层阴影不透明度?

即而不是

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

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

对于每一层。

【讨论】:

以上是关于单视图 iOS 上的多个投影的主要内容,如果未能解决你的问题,请参考以下文章

用于将匿名类型投影到视图模型上的 Automapper 查询

从 iOS 应用程序中的多个视图重复调用地理位置单例类

WebGL简易教程:第一个三维示例(使用模型视图投影变换)

iOS 8 键盘扩展 - UIInputViewController 无法添加多个视图 [关闭]

Xamarin 表单 - 列表视图上的多个标题

单例 iOS 中 removeFromSuperview 上的 EXC_BAD_ACCESS