CALayers旋转时变形不正确

时间:2019-04-25 16:16:11

标签: swift calayer

鉴于CALayers的排列如左图所示(背景,框架和文字层),我希望将其中的两个旋转45°(layer.transform = CATransform3DMakeRotation(.pi / 4, 0, 0, 1)),以使菱形位于右侧,但我看到的是中间的对角线。

Unrotated, rotated, expected

该元素包括父CALayer,背景层,边框框架层和文本层。我希望能够缩放和整体旋转元素,因此看不见的父层和两个预先旋转的子元素:

class ScoreLayer: CALayer {
    var score = 0 {
        didSet {
            updateValue()
        }
    }

    let bgLayer: CALayer = {
        let layer = CALayer()
        layer.contentsScale = UIScreen.main.scale
        layer.backgroundColor = #colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1)
        layer.shadowOffset = .zero
        layer.shadowRadius = 3
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOpacity = 0.4
        return layer
    }()

    let textLayer: CATextLayer = {
        let layer = CATextLayer()
        layer.contentsScale = UIScreen.main.scale
        layer.alignmentMode = .center
        layer.foregroundColor = UIColor.white.cgColor
        layer.fontSize = 20
        layer.font = UIFont.preferredFont(forTextStyle: .largeTitle)
        return layer
    }()

    let frameLayer: CALayer = {
        let layer = CALayer()
        layer.contentsScale = UIScreen.main.scale
        layer.borderColor = #colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1)
        layer.borderWidth = 3
        layer.shadowOffset = .zero
        layer.shadowRadius = 3
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOpacity = 0.7
        return layer
    }()

    override init() {
        super.init()
        contentsScale = UIScreen.main.scale

        addSublayer(bgLayer)
        addSublayer(textLayer)
        addSublayer(frameLayer)

        updateValue()
    }

    override func layoutSublayers() {
        bgLayer.frame = bounds
        frameLayer.frame = bounds
        textLayer.frame = bounds

        bgLayer.transform = CATransform3DMakeRotation(.pi / 4, 0, 0, 1)
        frameLayer.transform = CATransform3DMakeRotation(.pi / 4, 0, 0, 1)
    }

    private func updateValue() {
        textLayer.string = "\(score)"
    }
}

对旋转进行动画处理(通过CADisplayLink设置新的变换),看起来旋转的图层也好像绕着自己的x轴旋转。除了代码清单中的两个转换,我没有设置其他任何转换。

是什么原因造成的?

1 个答案:

答案 0 :(得分:0)

在应用变换后不更新帧。 .leastNormalMagnitude.被多次调用,并且复合效应是导致不必要的失真的原因。在应用变换之前,请在其他位置设置一次框架,或者,如果需要更新框架(可能是响应方向变化),请确保删除变换以更新框架,然后重新应用变换。

编辑后添加:

docs实际上明确地说“如果transform属性应用的旋转变换不是90度的倍数,则不要设置框架。”