如何根据设备大小调整 CAShapeLayer 的位置?

How to adjust position of CAShapeLayer based upon device size?

我正在尝试创建一个 CAShapeLayer 动画,它在 UILabel 的框架周围绘制轮廓。这是代码:

 func newQuestionOutline() -> CAShapeLayer {

        let outlineShape = CAShapeLayer()
        outlineShape.isHidden = false
        let circularPath = UIBezierPath(roundedRect: questionLabel.frame, cornerRadius: 5)
        outlineShape.path = circularPath.cgPath
        outlineShape.fillColor = UIColor.clear.cgColor
        outlineShape.strokeColor = UIColor.yellow.cgColor
        outlineShape.lineWidth = 5
        outlineShape.strokeEnd = 0
        view.layer.addSublayer(outlineShape)

        return outlineShape

    }

    func newQuestionAnimation() {

        let outlineAnimation = CABasicAnimation(keyPath: "strokeEnd")
        outlineAnimation.toValue = 1
        outlineAnimation.duration = 5
        newQuestionOutline().add(outlineAnimation, forKey: "key")

    }

当模拟器上的 运行 为 iPhone 11 时,动画按预期执行,这是我在故事板中使用的设备尺寸。但是,当 运行 项目在具有不同屏幕尺寸(如 iPhone 8 plus)的不同设备上时,形状被绘制错位而不是 UILabel 周围。我使用自动布局将 UILabel 水平和垂直居中到视图的中心,因此无论使用什么设备,UILabel 都居中。

有什么建议吗?提前致谢!

干杯!

形状图层不是视图,因此不受自动布局的影响。任何时候你说 roundedRect: questionLabel.frame 这样的话,你都在让自己依赖于 questionLabel.frame 那一刻 是什么 ,这是一个巨大的错误,因为这正是在自动布局确定框架将是什么之前未确定(并且如果自动布局由于条件变化(例如旋转等)而改变主意,则可以稍后更改)

有两种解决方法:

  • 在视图中托管形状图层。现在你有了一些受自动布局影响的东西。每当视图更改其框架时,您仍然需要重绘形状图层,但您可以检测到并执行重绘。

  • 实施您的视图控制器的 viewDidLayoutSubviews 以检测自动布局刚刚完成其工作。响应(例如)移除形状层并根据当前条件制作新的形状层。