У меня есть пользовательский UIView с 2 подслоями (CALayer). Я хочу изменить размер пользовательского UIView с анимацией. Подслои должны обрезать границы UIView.
Проблема: анимация подслоев отличается от пользовательской анимации UIView (см. Изображение в формате gif (красный: пользовательский вид; серый прямоугольник с подслоем углового радиуса))
Код
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
}
}
Вопрос : Как можно преобразовать различные анимации в единую анимацию?