您的位置:首页 > 其它

2.Animation的使用 - 创建一个可以自动切换界面的游戏登陆页面

2015-12-27 17:56 891 查看
前面我们已经搞定了一个小例子的Demo, 现在让我们接下来看更炫酷的动画界面:

PS: 已更新到Swift 2.0, 支持Xcode 7, iOS 9

1.界面布局



小细节



2.添加假数据



[code]import Foundation

struct FlightData {
  let summary: String
  let flightNr: String
  let gateNr: String
  let departingFrom: String
  let arrivingTo: String
  let weatherImageName: String
  let showWeatherEffects: Bool
  let isTakingOff: Bool
  let flightStatus: String
}

let londonToParis = FlightData(
  summary: "01 Apr 2015 09:42",
  flightNr: "ZY 2014",
  gateNr: "T1 A33",
  departingFrom: "LGW",
  arrivingTo: "CDG",
  weatherImageName: "bg-snowy",
  showWeatherEffects: true,
  isTakingOff: true,
  flightStatus: "Boarding")

let parisToRome = FlightData(
  summary: "01 Apr 2015 17:05",
  flightNr: "AE 1107",
  gateNr: "045",
  departingFrom: "CDG",
  arrivingTo: "FCO",
  weatherImageName: "bg-sunny",
  showWeatherEffects: false,
  isTakingOff: false,
  flightStatus: "Delayed")


3.***雪花控件



[code]import UIKit

class SnowView: UIView {

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

    let emitter = layer as! CAEmitterLayer

    emitter.emitterPosition = CGPoint(x: bounds.size.width / 2, y: 0)

    emitter.emitterSize = bounds.size

    emitter.emitterShape = kCAEmitterLayerRectangle

    let emitterCell = CAEmitterCell()

    emitterCell.contents = UIImage(named: "flake.png")!.CGImage

    emitterCell.birthRate = 200

    emitterCell.lifetime = 3.5

    emitterCell.color = UIColor.whiteColor().CGColor

    emitterCell.redRange = 0.0

    emitterCell.blueRange = 0.1

    emitterCell.greenRange = 0.0

    emitterCell.velocity = 10

    emitterCell.velocityRange = 350

    emitterCell.emissionRange = CGFloat(M_PI_2)

    emitterCell.emissionLongitude = CGFloat(-M_PI)

    emitterCell.yAcceleration = 70

    emitterCell.xAcceleration = 0

    emitterCell.scale = 0.33

    emitterCell.scaleRange = 1.25

    emitterCell.scaleSpeed = -0.25

    emitterCell.alphaRange = 0.5

    emitterCell.alphaSpeed = -0.15

    emitter.emitterCells = [emitterCell]
  }

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

  override class func layerClass() -> AnyClass {
    return CAEmitterLayer.self
  }
}


4.实现代码

声明一个枚举

[code]// 1.声明一个动画时间的枚举类型
enum AnimationDirection: Int {
    case Positive = 1
    case Negative = -1
}


关联控件

[code]class ViewController: UIViewController {
    // 2.关联控件
    @IBOutlet weak var bgImageView: UIImageView!

    @IBOutlet weak var summaryIcon: UIImageView!
    @IBOutlet weak var summary: UILabel!

    @IBOutlet weak var flightNr: UILabel!
    @IBOutlet weak var gateNr: UILabel!

    @IBOutlet weak var departingFrom: UILabel!
    @IBOutlet weak var arrivingTo: UILabel!
    @IBOutlet weak var planeImage: UIImageView!

    @IBOutlet weak var flightStatus: UILabel!
    @IBOutlet weak var statusBanner: UIImageView!

    // 3.实例化SnowView
    var snowView: SnowView!
}


设置viewDidLoad方法

[code]// 4.设置viewDidLoad
override func viewDidLoad() {
    super.viewDidLoad()

    // 4.1.把icon添加到summary中
    summary.addSubview(summaryIcon)

    // 4.2.使得icon的y轴等于summary高度的2分之1
    summaryIcon.center.y = summary.frame.size.height / 2

    // 4.3.初始化snowView的位置
    snowView = SnowView(frame: CGRect(x: -150, y: -100, width: 300, height: 50))

    // 4.4.实例化一个UIView视图, 并且设置它的位置为view.frame, dx轴为0, dy轴为50
    let snowClipView = UIView(frame: CGRectOffset(view.frame, 0, 50))

    // 4.4.设置超出该视图的控件都剪切掉
    snowClipView.clipsToBounds = true

    // 4.5.把之前设置好的snowView添加到snowClipView上
    snowClipView.addSubview(snowView)

    // 4.6.把设置好的snowClipView添加到self.view上
    view.addSubview(snowClipView)

    // 4.7.调用自定义好的changFlightDataTo方法, 并且把数据模型londonToParis作为参数传入
    changeFlightDataTo(londonToParis)
}


自定义更改数据的动画方法

[code]// 5.自定义更改内容的方法
func changeFlightDataTo(data: FlightData, animate: Bool = false) {
    // 5.1.判断animate是否为真
    if animate {
        // 5.2.调用自定义的飞机动画
        planeDepart()

        // 5.3.调用自定义的summary的文字切换动画
        summarySwitchTo(data.summary)

        // 5.4.调用自定义的背景图切换动画
        fadeImageView(bgImageView, toImage: UIImage(named: data.weatherImageName)!, showEffects: data.showWeatherEffects)

        // 5.5.获取动画方向, 判断isTakingOff是否为真, 如果为真就正方向, 否则就是反方向
        let direction: AnimationDirection = data.isTakingOff ? AnimationDirection.Positive : AnimationDirection.Negative

        // 5.6.调用自定义的文本切换动画, 并且把获取到的动画方向传入
        cubeTransition(label: flightNr, text: data.flightNr, direction: direction)
        cubeTransition(label: gateNr, text: data.gateNr, direction: direction)
        cubeTransition(label: flightStatus, text: data.flightStatus, direction: direction)

        // 5.7.获取Departing的文字切换偏移量
        let offsetDeparting = CGPoint(x: CGFloat(direction.rawValue * 80), y: 0.0)

        // 5.8.获取Arriving的文字切换偏移量
        let offsetArriving = CGPoint(x: 0.0, y: CGFloat(direction.rawValue * 50))

        // 5.9.调用自定义的文字切换动画, 并且把所要切换的x轴偏移量传入
        moveLabel(departingFrom, text: data.departingFrom, offset: offsetDeparting)

        // 5.10.调用自定义的文字切换动画, 并且把所要切换的y轴偏移量传入
        moveLabel(arrivingTo, text: data.arrivingTo, offset: offsetArriving)

    } else {
        // 5.11.把FlightData里的值依依赋给关联好的控件
        summary.text = data.summary
        flightNr.text = data.flightNr
        gateNr.text = data.gateNr
        departingFrom.text = data.departingFrom
        arrivingTo.text = data.arrivingTo
        flightStatus.text = data.flightStatus
        bgImageView.image = UIImage(named: data.weatherImageName)

        // 5.12.设置snowView的隐藏属性
        snowView.hidden = !data.showWeatherEffects
    }

    // 5.13.调用自定义好的延迟方法, 并且设置每隔三秒就会自动回调一次3.0秒
    delay(seconds: 3.0) {
        // 5.13.1.调用changeFlightDataTo方法, 并且在传入的参数中使用三目运算符, 判断data.isTakingOff是否为真, 如果是, 传入parisToRome, 否则就传入londonToParis
        self.changeFlightDataTo(data.isTakingOff ? parisToRome : londonToParis, animate: true)
    }
}


自定义切换背景图的动画方法

[code]// 6.自定义背景图淡入淡出的方法
func fadeImageView(imageView: UIImageView, toImage: UIImage, showEffects: Bool) {
    // 6.1.自定义transitionWithView, 传入外部ImageView, 设置好持续时间, 动画类型, 开始动画
    UIView.transitionWithView(imageView, duration: 1.0,
        options: .TransitionCrossDissolve, animations: {
            imageView.image = toImage
        }, completion: nil)

    // 6.2.自定义animateWithDuration, 设置好持续时间, 延迟时间, 动画类型, 开始动画
    UIView.animateWithDuration(1.0, delay: 0.0,
        options: .CurveEaseOut, animations: {
            // 6.3.判断snowView的透明度, 如果showEffects为真, 那么就显示, 否则就隐藏
            self.snowView.alpha = showEffects ? 1.0 : 0.0
        }, completion: nil)
}


自定义延迟动画的方法

[code]// 7.自定义一个延迟的方法
func delay(seconds seconds: Double, completion:()->()) {
    // 7.1.创建一个默认的时间值
    let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64( Double(NSEC_PER_SEC) * seconds ))

    // 7.2.在主线程中使用创建好的默认时间值
    dispatch_after(popTime, dispatch_get_main_queue()) {
        completion()
    }
}


自定义飞机的动画方法

[code]// 8.自定义飞机动画
func planeDepart() {
    // 8.1.获取飞机的中心点
    let originalCenter = planeImage.center

    // 8.2.自定义关键帧动画, 设置持续时间, 延迟时间, 动画类型, 开始动画
    UIView.animateKeyframesWithDuration(1.5, delay: 0.0, options: [], animations: {

        // 8.3.自定义关键帧动画开始的时间, 相对持续时间, 开始动画
        UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.25, animations: {
            // 8.3.1.设置飞机的x轴和y轴
            self.planeImage.center.x += 80.0
            self.planeImage.center.y -= 10.0
        })

        // 8.5.自定义关键帧动画开始的时间, 相对持续时间, 开始动画
        UIView.addKeyframeWithRelativeStartTime(0.1, relativeDuration: 0.4) {
            // 8.5.1.设置飞机的transform
            self.planeImage.transform = CGAffineTransformMakeRotation(CGFloat(-M_PI_4/2))
        }

        // 8.6.自定义关键帧动画开始的时间, 相对持续时间, 开始动画
        UIView.addKeyframeWithRelativeStartTime(0.25, relativeDuration: 0.25) {
            // 8.6.1.设置飞机的x轴, y轴, 以及透明度
            self.planeImage.center.x += 100.0
            self.planeImage.center.y -= 50.0
            self.planeImage.alpha = 0.0
        }

        // 8.7.自定义关键帧动画开始的时间, 相对持续时间, 开始动画
        UIView.addKeyframeWithRelativeStartTime(0.51, relativeDuration: 0.01) {
            // 8.7.1.设置飞机的transform, 中心点
            self.planeImage.transform = CGAffineTransformIdentity
            self.planeImage.center = CGPoint(x: 0.0, y: originalCenter.y)
        }

        // 8.8.自定义关键帧动画开始的时间, 相对持续时间, 开始动画
        UIView.addKeyframeWithRelativeStartTime(0.55, relativeDuration: 0.45) {
            // 8.8.1.设置飞机的透明度, 中心点
            self.planeImage.alpha = 1.0
            self.planeImage.center = originalCenter
        }

        }, completion: nil)
}


自定义内容切换的动画方法

[code]// 9.自定义切换动画
func summarySwitchTo(summaryText: String) {
    // 9.1.自定义关键帧动画, 设置持续时间, 延迟时间, 动画类型, 开始动画
    UIView.animateKeyframesWithDuration(1.0, delay: 0.0, options: [], animations: {

        // 9.2.自定义关键帧动画开始的时间, 相对持续时间, 开始动画
        UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.45, animations: {
            // 9.2.1.设置summary的y轴
            self.summary.center.y -= 100.0
        })
        // 9.3.自定义关键帧动画开始的时间, 相对持续时间, 开始动画
        UIView.addKeyframeWithRelativeStartTime(0.5, relativeDuration: 0.45, animations: {
            // 9.3.1.设置summary的y轴
            self.summary.center.y += 100.0
        })
        }, completion: nil)

    // 9.4.调用自定义的延迟方法
    delay(seconds: 0.5, completion: {
        // 9.4.1.设置summary的文本内容
        self.summary.text = summaryText
    })
}


自定义动画方向切换的方法

[code]// 10.自定义方向的切换动画
func cubeTransition(label label: UILabel, text: String, direction: AnimationDirection) {

    // 10.1.自定义一个UILabel, 位置大小和传入进来的Label位置大小一致
    let auxLabel = UILabel(frame: label.frame)

    // 10.2.获取传入进来的text内容
    auxLabel.text = text

    // 10.3.获取传入进来的Label文字大小
    auxLabel.font = label.font

    // 10.4.获取传入进来的Label文字位置
    auxLabel.textAlignment = label.textAlignment

    // 10.5.获取传入进来的Label文字颜色
    auxLabel.textColor = label.textColor

    // 10.6.设置auxLabel的背景颜色
    auxLabel.backgroundColor = label.backgroundColor

    // 10.7.设置auxLabl偏移量
    let auxLabelOffset = CGFloat(direction.rawValue) *
        label.frame.size.height/2.0

    // 10.8.设置auxLabel的transform属性, 并且把对应的大小, translation的属性传入
    auxLabel.transform = CGAffineTransformConcat(
        CGAffineTransformMakeScale(1.0, 0.1),
        CGAffineTransformMakeTranslation(0.0, auxLabelOffset))

    // 10.9.把auxLabel添加到传入进来的label.superview
    label.superview!.addSubview(auxLabel)

    // 10.10.自定义animateWithDuration动画, 设置开始时间, 延迟时间, 动画类型, 开始动画
    UIView.animateWithDuration(0.5, delay: 0.0, options: .CurveEaseOut, animations: {

        // 10.11.设置auxLabel的transform
        auxLabel.transform = CGAffineTransformIdentity

        // 10.12.设置auxLabel的transform属性, 并且把对应的大小, translation的属性传入
        label.transform = CGAffineTransformConcat(
            CGAffineTransformMakeScale(1.0, 0.1),
            CGAffineTransformMakeTranslation(0.0, -auxLabelOffset))
        // 10.13.动画完成之后
        }, completion: {_ in
            // 10.13.1.把auxLabel.text赋值给传入进来的label.text
            label.text = auxLabel.text

            // 10.13.2.设置传入进来的labeltransform属性
            label.transform = CGAffineTransformIdentity

            // 10.13.3.把auxLabel从superview中删除
            auxLabel.removeFromSuperview()
    })
}


自定义移动标签的动方法

[code]// 11.自定义移动标签的方法
func moveLabel(label: UILabel, text: String, offset: CGPoint) {

    // 11.1.自定义一个UILabel, 位置大小和传入进来的Label位置大小一致
    let auxLabel = UILabel(frame: label.frame)

    // 11.2.获取传入进来的text内容
    auxLabel.text = text

    // 11.3.获取传入进来的Label文字大小
    auxLabel.font = label.font

    // 11.4.获取传入进来的Label文字位置
    auxLabel.textAlignment = label.textAlignment

    // 11.5.获取传入进来的Label文字颜色
    auxLabel.textColor = label.textColor

    // 11.6.设置auxLabel的背景颜色
    auxLabel.backgroundColor = UIColor.clearColor()

    // 11.7.设置auxLabel的transform属性为传入进来的offset的x轴和y轴
    auxLabel.transform = CGAffineTransformMakeTranslation(offset.x, offset.y)

    // 11.8.设置auxLabel的透明度
    auxLabel.alpha = 0

    // 11.9.把设置好的auxLabel添加到view上
    view.addSubview(auxLabel)

    // 11.10.自定义animateWithDuration动画, 设置开始时间, 延迟时间, 动画类型, 开始动画
    UIView.animateWithDuration(0.5, delay: 0.0,
        options: .CurveEaseIn, animations: {
            // 11.10.1.设置传入进来的Label的transform属性为传入进来的offset的x轴和y轴
            label.transform = CGAffineTransformMakeTranslation(
                offset.x, offset.y)

            // 11.10.2.设置传入进来的Label透明度
            label.alpha = 0.0
        }, completion: nil)

    // 11.11.自定义animateWithDuration动画, 设置开始时间, 延迟时间, 动画类型, 开始动画
    UIView.animateWithDuration(0.25, delay: 0.1,
        options: .CurveEaseIn, animations: {
            // 11.11.1.设置传入进来的Label的transform属性为传入进来的offset的x轴和y轴
            auxLabel.transform = CGAffineTransformIdentity

            // 11.11.2.设置传入进来的Label透明度
            auxLabel.alpha = 1.0

            // 11.12.完成动画之后的操作
        }, completion: {_ in
            // 11.12.1.把auxLabel从Superview中删除
            auxLabel.removeFromSuperview()

            // 11.12.2.把传入进来的text赋值给传入进来的label.text
            label.text = text

            // 11.12.3.设置传入进来的label透明度
            label.alpha = 1.0

            // 11.12.4.设置传入进来的label的transform属性为恒等转变
            label.transform = CGAffineTransformIdentity
    })
}


5.最终效果



项目地址: 链接: http://pan.baidu.com/s/1pJp8NQ7 密码: qhr1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: