【问题标题】:How do I cast two shadows from an UIImageView with a SF Symbol as the image?如何使用 SF Symbol 从 UIImageView 投射两个阴影作为图像?
【发布时间】:2020-05-17 23:00:17
【问题描述】:

我想在图像的左下方和右下方投射阴影。但我正在努力获得第二个阴影投射(layer2)......

我创建了 UIImage 视图的子类并在 IB 中使用它:

import UIKit

class ShadowImageView: UIImageView {

    var layer2 = CALayer()

    override func layoutSubviews() {
        super.layoutSubviews()

        self.layer2 = CALayer(layer: self.layer)

        self.clipsToBounds = false

        self.layer.shadowColor = UIColor.gray.cgColor
        self.layer.shadowOffset = CGSize(width: -16, height: 16)
        self.layer.shadowOpacity = 0.33
        self.layer.shadowRadius = 3
        self.layer.masksToBounds = false

        self.layer2.shadowColor = UIColor.gray.cgColor
        self.layer2.shadowOffset = CGSize(width: 16, height: 16)
        self.layer2.shadowOpacity = 0.33
        self.layer2.shadowRadius = 3
        self.layer2.masksToBounds = false

        self.layer.insertSublayer(self.layer2, at: 0)

        print("\(self.layer)\n")
        if let sublayers = self.layer.sublayers {
            for layer in sublayers {
                print("\(layer)\n")
            }
        }
    }
}

我是在正确的方向复制图层并对其应用新的阴影,还是应该朝不同的方向看?

【问题讨论】:

  • 让我们阅读 CALayer 上的 docs init(layer:) —“此初始化程序用于创建图层的影子副本,例如,用于presentation() 方法。在任何其他情况下使用此方法将产生未定义的行为。例如,不要使用此方法使用现有图层的内容初始化新图层。那是你。不要。采用。这种方法。做你正在做的事情。它不会起作用。

标签: swift uiimageview calayer shadow


【解决方案1】:

修复了阴影问题。我能够通过在我的 UIView 上添加 3 层来生成双重阴影。最后面(视图层的第一个子层)是较暗的阴影,最上面的阴影是较浅的阴影,最上面的是正常颜色的阴影。

我正在通过应用阴影路径和颜色在图层上“绘制”图像。

我正在绘制的图像来自下面列出的方法,但它不是从 SFSymbols 生成的。我想在运行时生成它,所以我最终得到了一种使用符号在我们的应用程序中放置神经拟态元素的简单方法。这些 BezierPaths 的手动生成并不令人愉快。

static var shieldFill: UIBezierPath = {
    let bezierPath = UIBezierPath()
    bezierPath.move(to: CGPoint(x: 58.94, y: 115.53))
    bezierPath.addCurve(to: CGPoint(x: 62.84, y: 114.4), controlPoint1: CGPoint(x: 60.06, y: 115.53), controlPoint2: CGPoint(x: 61.57, y: 115.04))
    bezierPath.addCurve(to: CGPoint(x: 101.76, y: 74.46), controlPoint1: CGPoint(x: 91.5, y: 100.49), controlPoint2: CGPoint(x: 101.76, y: 91.89))
    bezierPath.addLine(to: CGPoint(x: 101.76, y: 39.94))
    bezierPath.addCurve(to: CGPoint(x: 92.04, y: 25.05), controlPoint1: CGPoint(x: 101.76, y: 31.84), controlPoint2: CGPoint(x: 99.41, y: 28.12))
    bezierPath.addCurve(to: CGPoint(x: 67.63, y: 16.85), controlPoint1: CGPoint(x: 87.89, y: 23.29), controlPoint2: CGPoint(x: 71.29, y: 17.97))
    bezierPath.addCurve(to: CGPoint(x: 58.94, y: 15.53), controlPoint1: CGPoint(x: 64.94, y: 16.11), controlPoint2: CGPoint(x: 61.52, y: 15.53))
    bezierPath.addCurve(to: CGPoint(x: 50.24, y: 16.85), controlPoint1: CGPoint(x: 56.35, y: 15.53), controlPoint2: CGPoint(x: 52.93, y: 16.11))
    bezierPath.addCurve(to: CGPoint(x: 25.83, y: 25.05), controlPoint1: CGPoint(x: 46.53, y: 17.97), controlPoint2: CGPoint(x: 29.93, y: 23.29))
    bezierPath.addCurve(to: CGPoint(x: 16.11, y: 39.94), controlPoint1: CGPoint(x: 18.46, y: 28.12), controlPoint2: CGPoint(x: 16.11, y: 31.84))
    bezierPath.addLine(to: CGPoint(x: 16.11, y: 74.46))
    bezierPath.addCurve(to: CGPoint(x: 55.03, y: 114.4), controlPoint1: CGPoint(x: 16.11, y: 91.89), controlPoint2: CGPoint(x: 26.46, y: 100.29))
    bezierPath.addCurve(to: CGPoint(x: 58.94, y: 115.53), controlPoint1: CGPoint(x: 56.3, y: 115.04), controlPoint2: CGPoint(x: 57.76, y: 115.53))
    bezierPath.close()

    return bezierPath
}()

【讨论】:

  • 你是如何应用第一张图片中显示的内阴影的?
  • 所有图像的阴影都相同。左上角较亮,右上角较暗。第一张图片基本上是一个开放的圆圈,所以阴影正好匹配那个形状。
  • 我已将我的测试项目邮寄给您。享受;-)
【解决方案2】:

我很容易得到这个:

这似乎是你所追求的。

双重阴影源于这样一个事实,即在图形上下文中,阴影绘制是应用于任何未来绘制的状态。因此,如果您将上下文的阴影设置为向下和向左并绘制符号图像,然后将上下文的阴影设置为向下和向右并绘制符号图像,您会得到双重阴影。

符号图像本身确实被绘制了两次,但这并不一定会改变它的出现方式;如果我没有告诉你我画了两次,我想你不会知道的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    相关资源
    最近更新 更多