CAGradientLayer messes up CATransform3DRotate

I am observing a strange behaviour in a CATransform3DRotate which I am applying to the layer of a view which is in front of a view whose layer has a CAGradientLayer .

When the gradient view is there, the transform animation kind of masks half of the view I am transforming and everything else in front of it too. If the gradient view is not there or does not sit behind the view, everything is fine.

Here's screenshots to show what I mean. You can clearly see how the rotated view is partially hidden and the slider below too.

向左翻转向右翻转

Since it looks like the gradient layer is on a different z-plane, I played around with it's z position but that didn't help. Also that still wouldn't explain to me how the completely unrelated UISlider is masked as well.

What am I doing wrong here?

Below is a completely self-contained UIViewController which illustrates my problem.

class TestViewController: UIViewController {
    private var gradientLayer: CAGradientLayer!
    private var flipContent: UILabel!
    private var flipView: UIView!
    private var gradientView: UIView!
    private var slider: UISlider!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
        setupGradientLayer()
    }

    @IBAction func didChangeValue(_ sender: UISlider) {
        var perspectiveTransform = CATransform3DIdentity
        perspectiveTransform.m34 = -0.002
        let rotateAngle = CGFloat(sender.value) * CGFloat(Double.pi)
        let flipTransform = CATransform3DRotate(perspectiveTransform, rotateAngle, 0, 1, 0)
        flipView.layer.transform = flipTransform
    }

    private func setupGradientLayer() {
        gradientLayer = CAGradientLayer()
        gradientLayer.colors = [
            UIColor(red: 74 / 255, green: 173 / 255, blue: 255 / 255, alpha: 1.0).cgColor,
            UIColor(red: 0 / 255, green: 94 / 255, blue: 215 / 255, alpha: 1.0).cgColor
        ]
        gradientLayer.frame = view.bounds
        gradientView.layer.insertSublayer(gradientLayer, at: 0)
    }

    private func setupViews() {
        gradientView = UIView(frame: CGRect(x: 10, y: 150, width: 200, height: 30))
        slider = UISlider(frame: CGRect(x: 10, y: 400, width: 200, height: 30))
        slider.minimumValue = 0
        slider.maximumValue = 1
        slider.addTarget(self, action: #selector(didChangeValue(_:)), for: .valueChanged)
        flipView = UIView(frame: CGRect(x: 10, y: 100, width: 200, height: 200))
        flipView.backgroundColor = UIColor.lightGray
        flipContent = UILabel(frame: CGRect(x: 10, y: 100, width: 100, height: 100))
        flipContent.text = "I will flip"

        flipView.addSubview(flipContent)
        view.addSubview(gradientView)
        view.addSubview(flipView)
        view.addSubview(slider)
    }
}

Add az translation to your transform :

var perspectiveTransform = CATransform3DIdentity
perspectiveTransform.m34 = -0.002
let rotateAngle = CGFloat(sender.value) * CGFloat(Double.pi)
perspectiveTransform = CATransform3DTranslate(perspectiveTransform, 0, 0, 300)
flipView.layer.transform = CATransform3DRotate(perspectiveTransform, rotateAngle, 0, 1, 0)

If you take a look at the Debug View Hierarchy, you can see that your views are in the same plan.

You can also set the zPosition (which is a kind of shorthand for z translation) :

flipView.layer.zPosition = 300
链接地址: http://www.djcxy.com/p/12884.html

上一篇: 使用grep进行负面匹配(匹配不包含foo的行)

下一篇: CAGradientLayer混淆了CATransform3DRotate