Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Launch Image Splash Screen Animation in SWIFT

I want to create a twitter like launch image for my ios app in swift.

I do understand the general problem with animated launch images, and I basically know the steps to create such an animation:

  1. Add a new view, right after the app launched, with the exact same content as the launchimage
  2. Animate that view
  3. Let the view disappear

I found this brilliant source: http://iosdevtips.co/post/88481653818/twitter-ios-app-bird-zoom-animation

But this guy uses a mask and I am not able to change his code to get the "real" twitter like animation without a mask, but just an animated (zoom in) image.

So how do I add a new view to the current view? If I use a subview, how do I identify that view later on the progress when I need to delete the subview in animationDidStop?

Oh and I'd love to do all that in the AppDelegate.

Here is my current approach:

Setting up the view in AppDelegate:

import UIKit
import QuartzCore

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var viewForLayer: UIView!
    var window: UIWindow?

    var emoji: CALayer {
      return viewForLayer.layer
    }

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

      self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
      // step 1: recreate the launch image

      self.emoji.backgroundColor = UIColor(red: 52/255, green: 52/255, blue: 52/255, alpha: 0).CGColor
      self.emoji.contents = UIImage(named: "SplashScreenEmoji")!.CGImage

      self.emoji.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
      self.emoji.anchorPoint = CGPoint(x: 0.5, y: 0.5)
      self.emoji.position = CGPoint(x: self.window!.frame.size.width/2, y: self.window!.frame.size.height/2)

      // self.window!.addSubview(viewForLayer) or
      viewForLayer.layer.addSublayer(emoji)

      // step 2: add the animation to that view
      animateEmoji()

      self.window!.makeKeyAndVisible()
      UIApplication.sharedApplication().statusBarHidden = true
      return true
    }
}

For the animation:

func animateEmoji() {
    let keyFrameAnimation = CAKeyframeAnimation(keyPath: "bounds")
    keyFrameAnimation.delegate = self
    keyFrameAnimation.duration = 1
    keyFrameAnimation.beginTime = CACurrentMediaTime() + 1 //add delay of 1 second
    let initalBounds = NSValue(CGRect: emoji.bounds)
    let secondBounds = NSValue(CGRect: CGRect(x: 0, y: 0, width: 90, height: 90))
    let finalBounds = NSValue(CGRect: CGRect(x: 0, y: 0, width: 1500, height: 1500))
    keyFrameAnimation.values = [initalBounds, secondBounds, finalBounds]
    keyFrameAnimation.keyTimes = [0, 0.3, 1]
    keyFrameAnimation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut), CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)]
    self.emoji.addAnimation(keyFrameAnimation, forKey: "bounds")
}

override func animationDidStop(anim: CAAnimation!, finished flag: Bool) {
    // step 3: remove the view
    self.viewForLayer.removeFromSuperview()
}

I always get an fatal error: unexpectedly found nil while unwrapping an Optional value, i guess this is because of the

var emoji: CALayer {
   return viewForLayer.layer
}

I definitely stuck and need the help of the stackoverflow community, please don't judge since I am new here and just learn how to code swift ;)

Thanks, jo

like image 894
Jo F.T. Avatar asked Oct 31 '22 05:10

Jo F.T.


1 Answers

You don't need to use layers, you can achieve your zoom effect simply via UIViews and UIView animation blocks.

Create a custom view controller with just an image view added to its view, assign that view controller as a window's rootViewController. Use a UIView animation block to increase the scale of the image view (via CGAffineTransform). In the animation's completion block, you can assign your actual initial view controller to the window's rootViewController.

like image 176
rounak Avatar answered Nov 15 '22 05:11

rounak