22 Apr

Data Container Singletons in Swift

 

 

SwiftDataContainerSingleton

A demonstration of using a data container singleton in Swift to save application state and share it between objects.

You can download the project from Github at this link: SwiftDataContainerSingleton.

Project Description:

The DataContainerSingleton class is the actual singleton.

It uses a static property sharedDataContainer to save a reference to the singleton.

The first time another object tries to reference the sharedDataContainer property, the code above creates the single instance of DataContainerSingleton and saves it in the sharedDataContainer property.

To access the singleton, use the syntax

The sample project defines 3 properties in the data container:

To load the someInt property from the data container, you’d use code like this:

To save a value to someInt, you’d use the syntax:

The DataContainerSingleton’s init method adds an observer for the UIApplicationDidEnterBackgroundNotification. That code looks like this:

In the observer code it saves the data container’s properties to NSUserDefaults. You can also use NSCoding, Core Data, or various other methods for saving state data.

The DataContainerSingleton’s init method also tries to load saved values for it’s properties.

That portion of the init method looks like this:

The keys for loading and saving values into NSUserDefaults are stored as string constants that are part of a struct DefaultsKeys, defined like this:

You reference one of these constants like this:

Using the data container singleton:


This sample application makes trival use of the data container singleton.

There are two view controllers. The first is a custom subclass of UIViewController ViewController, and the second one is a custom subclass of UIViewController SecondVC.

Both view controllers have a text field on them, and both load a value from the data container singlelton’s someInt property into the text field in their viewWillAppear method, and both save the current value from the text field back into the `someInt’ of the data container.

The code to load the value into the text field is in the viewWillAppear: method:

The code to save the user-edited value back to the data container is in the view controllers’ textFieldShouldEndEditing methods:

You should load values into your user interface in viewWillAppear rather than viewDidLoad so that your UI updates each time the view controller is displayed.

 

22 Apr

Keyframe View Animations

 

Keyframe View Animations

A project that demonstrates a number of iOS animation techniques. You can download the working Xcode project for this article from Github at this link: KeyframeViewAnimations

Animating a view/layer along a curved path using 2 different types of keyframe animation:

  1. Using the new UIView animation method animateKeyframesWithDuration:delay:options:animations:completion:

  2. Using a CAKeyframeAnimation with an array of position values.

 

Rotating a view/layer > 180º

animating the view’s transform using a CAValueFunction of type “kCAValueFunctionRotateZ”.

 

Pausing and resuming an “in flight” animation on a layer.

All of the animations in this demo can be paused by clicking a pause/continue button, stopped with a stop button, or “scrubbed” back and forth along their timeline by dragging on a slider.

This works for UIView animations as well as animations you create using CAAnimation objects. It works because UIView aniamtions create CAAnimation objects “under the covers” to perform the requested animation.

This is done by manipulating the layer’s speed, beginTime, and timeoffset properties.

 

Sleuthing the animations created by UIView animation methods

It’s possible to watch the animations that iOS creates when you use UIView animation methods like animateWithDuration:animations: or animateKeyframesWithDuration:delay:options:animations:completion:. Take a look at  this article on sleuthing uiview animations.

 

18 Apr

Password Generator

This sample project generates passwords using random words from a large word list available on the internet.

It illustrates several useful techniques:

  • Parsing raw text into a binary plist and adding that plist to your application
  • Reading a plist from your application bundle to load saved resources
  • Using the arc4random() function to pick random words from an array

You can download the project from Github at the following link:

Password generator project on Github

18 Apr

Using Core Animation Groups to Create Animation Sequences

 

iOS-CAAnimation-group-demo

This is a demo project that illustrates various animation techniques

It shows 3 different kinds of animations:

  • A simple UIView animation that animates an image in a straight line while increasing the scale of the image and rotating it around it’s axis
  • A “clock wipe” animation that gradually reveals an image in a circular arc like a radar display, then hides it again
  • A complex sequence of animations that are managed using a CAAnimationGroup.

UIVIew animation (View Animation button)

The UIView animation is performed by the method -doViewAnimation: (id) sender in viewController.m. It uses the method animateWithDuration:delay:options:animations:completion: to do it’s job. UIView animations modify animatable properties of one or more views. It is possible to animate mutliple animatable properties of multiple view objects with a single UIView animation call. the doViewAnimation method animates the view’s center, scale, and rotation all at the same time.

Clock Wipe animation (Mask Animation button)

The clock wipe animation is performed in the method - (IBAction)doMaskAnimation:(id)sender;. It works by creating a shape layer (CAShapeLayer) and setting it as the mask for an image view’s layer. We set the shape layer to contain a an arc that describes a full circle, where the radius of the arc is 1/2 of the center-to-corner distance of the view. The line width of the arc is set to the arc radius, so the arc actually fills the entire image bounds rectangle.

CAShapeLayers have a properties strokeStart and strokeEnd. Both values range from 0.0 to 1.0. Normally strokeStart = 0 and strokeEnd = 1.0. If you set strokeEnd to a value less than 1, only a portion of the shape layer’s path is drawn.

The doMaskAnimation method sets strokeEnd = 0 to start, which means the path is empty, and the entire image view is hidden (masked.) It then creates a CABasicAnimatimation that animates the strokeEnd property from 0.0 to 1.0. That causes the layer’s path to animate an ever-increasing arc. Since the line thickness for hte shape layer is very thick, the arc fills the entire bounds of the image view, revealing an ever-increasing portion of the image view.

The animation looks like this:

Clock wipe

CAAnimationGroup animation. (CAAnimation button)

The “CAAnimation” button invokes the method - (IBAction)doAnimation:(id)sender. It performs a whole sequence of animations. It does this buy creating a CAAnimationGroup, and then creating a sequence of individual CAAnimation objects of different flavors. It sets the beginTime property of each animation so that each animation step in the animation group begins when the next animation finishes.

What you will learn:

This project demonstrates a wide variety of animation techniques

  • Using CABasicAnimation to animate a property and move images around on the screen.
  • Using different animation timing functions like kCAMediaTimingFunctionLinear, kCAMediaTimingFunctionEaseIn, and kCAMediaTimingFunctionEaseInEaseOut to get different effects
  • Using CAKeyframeAnimation and a CGPath to animate a layer along a curved path (a figure 8).
  • Creating a custom subclass of UIView that has a CAShapeLayer as it’s backing layer so you can draw shapes in a view “for free.”
  • Adding a CGPath to a shape layer to draw shapes on the screen.
  • Using CAAnimationGroup to create a linked series of animations that run in sequence
  • Creating a very clean “per animation” completion block scheme using the fact that CAAnimation objects support the setValue:forKey: method. I add a code block to an animation object and set up the animation delegate’s animationDidStop:finished method to check for a special key/value pair with the key kAnimationCompletionBlock.
  • Using the cumulative property on animations to create a single repeating animation that continuously rotates a layer by any desired amount.
  • Using a CATapGestureRecognizer to detect taps on a view.
  • Detecting taps on a view while it animates “live” by using the hitTest method of the view’s presentation layer
  • Pausing and resuming animation on a layer.