изменение размера анимации UIView: время подслоя отличается - PullRequest
0 голосов
/ 26 февраля 2020

У меня есть пользовательский UIView с 2 подслоями (CALayer). Я хочу изменить размер пользовательского UIView с анимацией. Подслои должны обрезать границы UIView.

Проблема: анимация подслоев отличается от пользовательской анимации UIView (см. Изображение в формате gif (красный: пользовательский вид; серый прямоугольник с подслоем углового радиуса))

Gif demonstrate Problem

Код

ViewController


class ViewController: UIViewController {

       override func viewDidLoad() {
            super.viewDidLoad()
            self.view.backgroundColor = UIColor(red: (224/255), green: (229/255), blue: (239/255), alpha: 1.0)            
            var testButton = SoftButton(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
            self.view.addSubview(testButton)
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
                testButton.resize(direction: .toBottomRight)
            })
        }
}

Пользовательская кнопка


import UIKit

class SoftButton: UIView {

    enum LayerDesign{
        case light
        case dark
    }

    enum resizeDirection{
        case toTopLeft
        case toTopRight
        case toBottomLeft
        case toBottomRight
    }

    var layerShadow_light   : CALayer?  = nil
    var layerShadow_dark    : CALayer?  = nil

    let lightColor = UIColor(red:0.88, green:0.90, blue:0.93, alpha:1.0)


    override init(frame: CGRect) {
        super.init(frame: frame)
        initalSequence()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
        self.layerShadow_light?.frame = self.bounds
        self.layerShadow_dark?.frame  = self.bounds
    }


    func initalSequence(){
        print("initalSequence")
        self.backgroundColor = UIColor.red
        if self.layerShadow_light == nil{
            self.layerShadow_light = makelayer(type: .light)
            self.layer.addSublayer(self.layerShadow_light!)
        }
        if self.layerShadow_dark == nil{
            self.layerShadow_dark = makelayer(type: .dark)
            self.layer.addSublayer(self.layerShadow_dark!)
        }
    }



    private func makelayer(type: LayerDesign) -> CALayer{
        let layer = CALayer()
        switch type {
        case .dark:
            layer.frame = self.bounds
            layer.backgroundColor = lightColor.cgColor
            layer.shadowColor = UIColor(red:0.64, green:0.69, blue:0.78, alpha:1.0).cgColor
            layer.shadowOpacity = 0.5
            layer.shadowOffset = CGSize(width: 6, height: 6)
            layer.shadowRadius = 6
            layer.cornerRadius = 12
        case .light:
            layer.frame = self.bounds
            layer.backgroundColor = lightColor.cgColor
            layer.shadowColor = UIColor.white.cgColor
            layer.shadowOpacity = 0.8
            layer.shadowOffset = CGSize(width: -6, height: -6)
            layer.shadowRadius = 6
            layer.cornerRadius = 12
        }
        return layer
    }





    func resize(direction: resizeDirection){
        print("resize  called")
        guard let superView = self.superview else{
            print("ERROR SoftButton resize: superview not found")
            return
        }
        switch direction {
        case .toTopLeft:
            print("test")
        case .toTopRight:
            print("test")
        case .toBottomLeft:
            print("test")
        case .toBottomRight:
            let anchorPoint = CGPoint(x: 0, y: 0)
            self.setAnchorPoint(anchorPoint)
            self.layerShadow_light?.anchorPoint = anchorPoint
            self.layerShadow_dark?.anchorPoint = anchorPoint
            self.layerShadow_dark?.setAnchorPoint(anchorPoint: anchorPoint)
            self.layerShadow_light?.setAnchorPoint(anchorPoint: anchorPoint)
            superView.bringSubviewToFront(self)

            UIView.animate(withDuration: 2.3, delay: 0.0, options: [.curveLinear], animations: {
                self.bounds = CGRect(x: self.frame.minX, y: self.frame.minY, width: 200, height: 200)
            }, completion: nil)


            print("test")
        }

    }
}

Расширение

extension CALayer{
    func setAnchorPoint(anchorPoint: CGPoint) {
        var newPoint = CGPoint(x: self.bounds.size.width * anchorPoint.x, y: self.bounds.size.height * anchorPoint.y)
        var oldPoint = CGPoint(x: self.bounds.size.width * self.anchorPoint.x, y: self.bounds.size.height * self.anchorPoint.y)
        newPoint = newPoint.applying(self.affineTransform())
        oldPoint = oldPoint.applying(self.affineTransform())

        var position = self.position
        position.x -= oldPoint.x
        position.x += newPoint.x
        position.y -= oldPoint.y
        position.y += newPoint.y

        self.position = position
        self.anchorPoint = anchorPoint
    }
}

extension UIView {
    func setAnchorPoint(_ point: CGPoint) {
        var newPoint = CGPoint(x: bounds.size.width * point.x, y: bounds.size.height * point.y)
        var oldPoint = CGPoint(x: bounds.size.width * layer.anchorPoint.x, y: bounds.size.height * layer.anchorPoint.y);

        newPoint = newPoint.applying(transform)
        oldPoint = oldPoint.applying(transform)

        var position = layer.position

        position.x -= oldPoint.x
        position.x += newPoint.x

        position.y -= oldPoint.y
        position.y += newPoint.y

        layer.position = position
        layer.anchorPoint = point
    }
}

Вопрос : Как можно преобразовать различные анимации в единую анимацию?

...