iOS 基于CALayer的系统转场动画(CATransition)

1. 前言

针对CATransition转场动画,苹果系统已经给我们提供了很丰富的动画效果,本文将对系统提供的进行阐述,方便自己,同时也希望方便各位同仁更好的运用到自己的项目中去。

2. CATransition概述

An object that provides an animated transition between a layer's states.

一个在图层状态之间提供动画转换的对象。

class CATransition : CAAnimation

通俗点说就是有这么一个动画对象,他们够让图层在变化或者转换的时候提供一个过渡的动画。我们可以通过创建和添加一个CATransition对象来转换层的状态,默认的转换是渐变(fade),下面来看一个官方的示例:

class ViewController: UIViewController {
    
    let transitioningLayer = CATextLayer()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.systemGray5
        textLayerChangeTest()
    }

    func textLayerChangeTest() {
        transitioningLayer.frame = CGRect(x:50, y: 100, width: 320, height: 160)
        view.layer.addSublayer(transitioningLayer)
        
        // Initial "red" state
        transitioningLayer.backgroundColor = UIColor.red.cgColor
        transitioningLayer.string = "Red"
    }

    func runTransition() {
        let transition = CATransition()
        transition.duration = 2
        transition.type = .push
        transitioningLayer.add(transition, forKey: "transition")
        
        // Transition to "blue" state
        transitioningLayer.backgroundColor = UIColor.blue.cgColor
        transitioningLayer.string = "Blue"
    }
    
    
    @IBAction func changeAction(_ sender: UIButton) {
        runTransition()
    }
}

3. CATransition属性

因为CATransition继承于CAAnimation,关于继承的属性,这里就不做赘述了,来看看CATransition自己的属性吧。

type

指定预定义的转换类型。系统提供了4中预设的可选值(公开API),除了前4个预设值,还有很多类型(私有API,慎用,小心审核不通过)可以设置,具体如下:

  1. fade:淡入淡出。不支持subType,设置无效。
  2. moveIn:慢慢进入并覆盖原始。
  3. push:推进效果。
  4. reveal:揭开效果。
  5. cube:立方体效果。
  6. suckEffect:吮吸效果。不支持subType,设置无效。iOS13及以上版本不支持该动画了。
  7. oglFlip:翻转效果。
  8. rippleEffect:波纹效果。不支持subType,设置无效。iOS13及以上版本不支持该动画了。
  9. pageCurl:翻页效果。
  10. pageUnCurl:反翻页效果。
  11. cameraIrisHollowOpen:开镜头效果。不支持subType,设置无效。iOS13及以上版本不支持该动画了。
  12. cameraIrisHollowClose:关镜头效果。不支持subType,设置无效。iOS13及以上版本不支持该动画了。

注:前4个为系统已经定义的CATransitionType类型的值,可以直接设置,后面的则是字符串类型,设置的时候需要构建CATransitionType对象,例如:CATransitionType(rawValue: "cube")

subType

指定一个可选的子类型,该子类型指示type的动画方向。

  1. fromRight:从图层的右侧开始转换。
  2. fromLeft:从图层的左侧开始转换。
  3. fromTop:从图层的上面开始转换。
  4. fromBottom:从图层的下面开始转换。

4. 属性使用示例及效果

还是基于上面的Demo,将上面所有type类型放到UICollectionView中,每单击一次cell,切换一次subType。以下效果是基于iOS12及以下设备运行结果:

      

      

      

源代码如下:

import UIKit

enum Type {
    case fade
    case moveIn
    case push
    case reveal
    case cube
    case suckEffect
    case oglFlip
    case rippleEffect
    case pageCurl
    case pageUnCurl
    case cameraIrisHollowOpen
    case cameraIrisHollowClose
    
    var value: CATransitionType {
        switch self {
        case .fade:
            return .fade
        case .moveIn:
            return .moveIn
        case .push:
            return .push
        case .reveal:
            return .reveal
        case .cube:
            return CATransitionType(rawValue: "cube")
        case .suckEffect:
            return CATransitionType(rawValue: "suckEffect")
        case .oglFlip:
            return CATransitionType(rawValue: "oglFlip")
        case .rippleEffect:
            return CATransitionType(rawValue: "rippleEffect")
        case .pageCurl:
            return CATransitionType(rawValue: "pageCurl")
        case .pageUnCurl:
            return CATransitionType(rawValue: "pageUnCurl")
        case .cameraIrisHollowOpen:
            return CATransitionType(rawValue: "cameraIrisHollowOpen")
        case .cameraIrisHollowClose:
            return CATransitionType(rawValue: "cameraIrisHollowClose")
        }
    }
    
    var text: String {
        switch self {
        case .fade:
            return "fade"
        case .moveIn:
            return "moveIn"
        case .push:
            return "push"
        case .reveal:
            return "reveal"
        case .cube:
            return "cube"
        case .suckEffect:
            return "suckEffect"
        case .oglFlip:
            return "oglFlip"
        case .rippleEffect:
            return "rippleEffect"
        case .pageCurl:
            return "pageCurl"
        case .pageUnCurl:
            return "pageUnCurl"
        case .cameraIrisHollowOpen:
            return "cameraIrisHollowOpen"
        case .cameraIrisHollowClose:
            return "cameraIrisHollowClose"
        }
    }
}

class ViewController: UIViewController {
    
    @IBOutlet weak var collectionView: UICollectionView!
    @IBOutlet weak var textLabel: UILabel!
    
    let typeArray: Array<Type> = [.fade, .moveIn, .push, .reveal, .cube, .suckEffect, .oglFlip, .rippleEffect, .pageCurl, .pageUnCurl, .cameraIrisHollowOpen, .cameraIrisHollowClose]
    var subTypeIndex: Int = 0
    var currentType: Type = .fade

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.white
        self.title = "导航栏"
        initCollectionView()
        initTextLabel()
    }
    
    func initCollectionView() {
        collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "Cell")
        collectionView.backgroundColor = UIColor.orange
        collectionView.delegate = self
        collectionView.dataSource = self
    }
    
    func initTextLabel() {
        textLabel.backgroundColor = UIColor.red
        textLabel.text = "Red"
    }

    func runTransition(type: Type) {
        if currentType.text != type.text {
            subTypeIndex = 0
        }
        currentType = type
        var subType: CATransitionSubtype?
        var toColor: UIColor?
        var toString: String = ""
        switch subTypeIndex {
        case 0:
            subType = .fromRight
            toColor = UIColor.blue
            toString = "Blue"
        case 1:
            subType = .fromLeft
            toColor = UIColor.purple
            toString = "Purple"
        case 2:
            subType = .fromTop
            toColor = UIColor.cyan
            toString = "Cyan"
        case 3:
            subType = .fromBottom
            toColor = UIColor.red
            toString = "Red"
        default:
            subType = .none
        }
        subTypeIndex += 1
        if subTypeIndex > 3 {
            subTypeIndex = 0
        }
        
        let transition = CATransition()
        transition.duration = 0.8
        transition.type = type.value
        transition.subtype = subType
        
        textLabel.layer.add(transition, forKey: "transition")
        textLabel.backgroundColor = toColor
        textLabel.text = toString + "\n\n" + type.text
        
        // 如果将动画添加到navigation的view上,则会进行Controller之间的切换。
//        let detailVC = DetailViewController(nibName: "DetailViewController", bundle: nil)
//        self.navigationController?.view.layer.add(transition, forKey: "transition")
//        self.navigationController?.pushViewController(detailVC, animated: false)
    }
    
}

extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return typeArray.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? CollectionViewCell else {
            return UICollectionViewCell()
        }
        let type = typeArray[indexPath.item]
        cell.textLabel.text = type.text
        return cell
    }
}

extension ViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: (collectionView.bounds.size.width-30.0)/2, height: 40.0)
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let type = typeArray[indexPath.item]
        runTransition(type: type)
    }
}

查看原项目请点击:Demo传送门

5. 结束语

本文主要介绍了CATransition的一些动画类型,并附带测试demo以及运行效果,除了前4个type类型是苹果公开的,剩下的都是私有API,真正发开中要慎用,另外私有API中有些动画效果在iOS13及以上的系统设备上已经失效了,如果设置,则默认是fade效果。

CATransition动画主要是加到CALayer中的,针对UIView还有四个动画,这里就不过多阐述了,想了解的点击这里UIView.AnimationTransition

本篇文章出自https://blog.csdn.net/guoyongming925的博客,如需转载,请标明出处。

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值