简体   繁体   中英

Animating CALayer is not working on iOS 14

I have a problem with animating CALayer after updating to Xcode12 and iOS14 - animations that used to work on iOS13 are not working on iOS14. Here is the code for animations:

private func animateCellPress() {
    let lightShadowAnimation = CABasicAnimation(keyPath: "shadowOffset")
    lightShadowAnimation.fromValue = CGSize(width: -self.shadowRadius, height: -self.shadowRadius)
    lightShadowAnimation.toValue = CGSize(width: self.shadowRadius, height: self.shadowRadius)
    lightShadowAnimation.fillMode = .forwards;
    lightShadowAnimation.isRemovedOnCompletion = false;
    lightShadowAnimation.duration = self.animationDuration
    self.lightShadow.add(lightShadowAnimation, forKey: lightShadowAnimation.keyPath)

    let darkShadowAnimation = CABasicAnimation(keyPath: "shadowOffset")
    darkShadowAnimation.fromValue = CGSize(width: self.shadowRadius, height: self.shadowRadius)
    darkShadowAnimation.toValue = CGSize(width: -self.shadowRadius, height: -self.shadowRadius)
    darkShadowAnimation.fillMode = .forwards;
    darkShadowAnimation.isRemovedOnCompletion = false;
    darkShadowAnimation.duration = self.animationDuration
    self.darkShadow.add(darkShadowAnimation, forKey: darkShadowAnimation.keyPath)
}

lightShadow and darkShadow are stored as a properties and here is the initialisation code for them:

private func initializeDarkShadow() {
    darkShadow = CALayer()
    darkShadow.frame = bounds
    darkShadow.backgroundColor = backgroundColor?.cgColor
    darkShadow.cornerRadius = cornerRadius
    darkShadow.shadowOffset = CGSize(width: shadowRadius, height: shadowRadius)
    darkShadow.shadowOpacity = 1
    darkShadow.shadowRadius = shadowRadius
    darkShadow.shadowColor = Asset.Colors.darkShadow.color.cgColor
    let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: bounds.size)
    darkShadow.shadowPath = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
    layer.insertSublayer(darkShadow, at: 0)
}

private func initializeLightShadow() {
    lightShadow = CALayer()
    lightShadow.frame = bounds
    lightShadow.backgroundColor = backgroundColor?.cgColor
    lightShadow.cornerRadius = cornerRadius
    lightShadow.shadowOffset = CGSize(width: -shadowRadius, height: -shadowRadius)
    lightShadow.shadowOpacity = 1
    lightShadow.shadowRadius = shadowRadius
    lightShadow.shadowColor = Asset.Colors.lightShadow.color.cgColor
    let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: bounds.size)
    lightShadow.shadowPath = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
    layer.insertSublayer(lightShadow, at: 0)
}

Any ideas on what's wrong and how can I fix it? Also I am not getting any compiler errors or warnings. Console log is empty as well.

This works. I think each time you are calling your animate layoutSubviews is being called thus removing the layer and the animation. You could either just update the frame there or check if the layer has already been added. If that is not the issue then there is something wrong with you press or touch function. Create a project with a single view and copy and paste this into your ViewController file.

import UIKit

class TableViewCell : UITableViewCell{
    let darkShadowColor = UIColor.green
    let lightShadowColor = UIColor.red
    let animationDuration : Double = 2
    
    var darkShadow = CALayer()
    var lightShadow = CALayer()
    let cornerRadius : CGFloat = 4
    let shadowRadius : CGFloat = 3
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        initializeDarkShadow()
        initializeLightShadow()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        initializeDarkShadow()
        initializeLightShadow()
    }
    
    private func initializeDarkShadow() {
        darkShadow = CALayer()
        darkShadow.frame = bounds
        darkShadow.backgroundColor = backgroundColor?.cgColor
        darkShadow.cornerRadius = cornerRadius
        darkShadow.shadowOffset = CGSize(width: shadowRadius, height: shadowRadius)
        darkShadow.shadowOpacity = 1
        darkShadow.shadowRadius = shadowRadius
        darkShadow.shadowColor = darkShadowColor.cgColor
        let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: bounds.size)
        darkShadow.shadowPath = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
        layer.insertSublayer(darkShadow, at: 0)
    }

    private func initializeLightShadow() {
        lightShadow = CALayer()
        lightShadow.frame = bounds
        lightShadow.backgroundColor = backgroundColor?.cgColor
        lightShadow.cornerRadius = cornerRadius
        lightShadow.shadowOffset = CGSize(width: -shadowRadius, height: -shadowRadius)
        lightShadow.shadowOpacity = 1
        lightShadow.shadowRadius = shadowRadius
        lightShadow.shadowColor = lightShadowColor.cgColor
        let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: bounds.size)
        lightShadow.shadowPath = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
        layer.insertSublayer(lightShadow, at: 0)
    }
    
    func animateCellPress() {
        print("called")
        let lightShadowAnimation = CABasicAnimation(keyPath: "shadowOffset")
        lightShadowAnimation.fromValue = CGSize(width: -self.shadowRadius, height: -self.shadowRadius)
        lightShadowAnimation.toValue = CGSize(width: self.shadowRadius, height: self.shadowRadius)
        lightShadowAnimation.beginTime = CACurrentMediaTime()
        lightShadowAnimation.fillMode = .both;
        lightShadowAnimation.isRemovedOnCompletion = false;
        lightShadowAnimation.duration = self.animationDuration
        self.lightShadow.add(lightShadowAnimation, forKey: nil)


        let darkShadowAnimation = CABasicAnimation(keyPath: "shadowOffset")
        darkShadowAnimation.fromValue = CGSize(width: self.shadowRadius, height: self.shadowRadius)
        darkShadowAnimation.toValue = CGSize(width: -self.shadowRadius, height: -self.shadowRadius)
        darkShadowAnimation.beginTime = CACurrentMediaTime()
        darkShadowAnimation.fillMode = .both;
        darkShadowAnimation.isRemovedOnCompletion = false;
        darkShadowAnimation.duration = self.animationDuration
        self.darkShadow.add(darkShadowAnimation, forKey: nil)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        self.lightShadow.frame = self.bounds
        self.darkShadow.frame = self.bounds
    }
}

class ViewController: UIViewController {

    let identifier = "someCellID"
    lazy var tableView : UITableView = {
        let tv = UITableView(frame: self.view.bounds)
        tv.delegate = self
        tv.dataSource = self
        tv.autoresizingMask = [.flexibleWidth,.flexibleHeight]
        tv.register(TableViewCell.self, forCellReuseIdentifier: identifier)
        return tv
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        self.view.addSubview(tableView)
    }
}

extension ViewController : UITableViewDelegate,UITableViewDataSource{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 20
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath) as? TableViewCell{
            cell.selectionStyle = .none
            return cell
        }
        print("error")
        return UITableViewCell()
    }
    
    
    
    func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {
        if let cell = tableView.cellForRow(at: indexPath) as? TableViewCell{
            cell.animateCellPress()
        }
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 50
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM