UIKit Animation (Part 1)

https://www.raywenderlich.com/5304228-ios-animation-tutorial-getting-started

Prerequisite → Strong understanding of Auto layout

Animation:

A change in value or state over time.

https://www.raywenderlich.com/18411703-uikit-animation/lessons/2

Animate Constraint Constant

As shown in Figure 1, we created a view with an initial height of 0 when the user tap on the toggle button, we will change its height at run time and with animation

Figure 1

When the user tap on the toggle height button, we change the height constraint constant using the reference constraint outlet. If the constraint has changed your layout will automatically be marked as needing an update. This means that UIKit knows it has to update the layout for you and that’s why we saw the view height updated. We can also force auto layout updates to happen on demand you can ask for view to be laid out immediately by calling layoutIfNeeded method. Currently if you tap on button it will update it’s height but not in a animated way. Now let’s add animation effect (smooth height change).

So in short if you change constraint it will update your view on next render pass and if you call layoutIfNeeded it will do in same render cycle

Figure 2

As shown in Gif 1 after put force layout update on animation block using UIView.animate , you can feel the animation effect. It will change the height of View with the animation duration 0.5, and start immediately since we added delay with 0 value

duration → The total duration of the animations, measured in seconds. If you specify a negative value or 0, the changes are made without animating them.

delay → The amount of time (measured in seconds) to wait before beginning the animations. Specify a value of 0 to begin the animations immediately.

options → A mask of options indicating how you want to perform the animations. For a list of valid constants, see UIView.AnimationOptions.

animations →A block object containing the changes to commit to the views. This is where you programmatically change any animatable properties of the views (like height, position) in your view hierarchy. This block takes no parameters and has no return value. This parameter must not be NULL.

completion →A block object to be executed when the animation sequence ends. This block has no return value and takes a single Boolean argument that indicates whether or not the animations actually finished before the completion handler was called. If the duration of the animation is 0, this block is performed at the beginning of the next run loop cycle. This parameter may be NULL.

Gif 1

Actually calling layoutIfNeeded will update the center in bounds for every view in the layout Any change that can be animated will be animated

As shown in Gif 2 when the toggle value is On we change the toggle button top constraint and view height and we only call layoutIfNeeded one time only it will update all the pending constraint in the same render cycle

Gif 2

UIView Animation Options

To understand animation, options we will create a textfield and when user tap on toggle button , textfield will appear on the screen from left to right in an animated way . As shown in Figure 4 we created texfield and added view constraint , width ≥ 200 , center X,

Figure 4

As shown in Figure 5.1 and 5.2 ,initially we make thhe view to be outof screen by manipulating it’s centerX constrint outlet reference

Figure 5.1
Figure 5.2

.curveEaseIn

This one is moving slowly at first and then speeds up towards the end of the animation as shown in gif 3

Gif 3

.autoreverse → Combined with .repeat this will loop the animation indefinitely. Just using autoreverse will do the initial animation but in reverse, and then snap back to the end position of the initial animation

.curveEaseOut → Much easier to see than .curveEaseOut this option begins with the animation moving quickly and then slows down at the end.

.curveEaseInOut → Moves slowly at first, speeds up over middle portion, then slows down at the end of the animation.

.curveLinear → Animation occurs evenly across the whole duration.

.repeat → Simply repeats the animation, which means it is sent back to the starting position of the animation.

.autoreverse with .repeat → Autoreverse sends the animation back to its original position, .repeat then repeats that process so it looks like the image is moving in an infinite loop as shown in gif4

Gif 4

You can all gif compelet visual exapaation on this blog written by Alex Mason. There are other animation options which are relevant to transition will talk later in this blog

https://itnext.io/swift-uiview-lovely-animation-and-transition-d34bd623391f

Dynamic View Animation

As shown in Figure 6, when we tap on the button, it will do a few things

  1. Created a view and added constraints to met the linear equation constraint formula
  2. Created an aspect ratio 1:1 (by adding the relationship between width and height constraints)
Figure 6

As shown in Gif 5, the animation is starting from the upper left corner, it should start from the one we showed in Figure 3 it seems the layout engine is ignoring out starting constraints. It because we never called layoutIfNeeded to settle the starting point and when we force layout it don’t have starting point so it starts from upper left corner

Gif 5

As shown in Figure 7, we settled the starting point by calling self.view.layoutIfNeeded() and then do the animation, Now run the with this code you can see animation will start with this starting point

Figure 7

Now let’s add hide animation as well after 2 seconds delay it will reset the values as well to show the hiding effect

Figure 8

Animate Constraint Multiplier

As shown in Figure 9, we have view that have height = 0.25 * superview using multiplier, which is main rootView, Now when user tap on toggle button we will animate multiplier to 0.5

Figure 9

Constraints are held by the closest view that contains both items in the constraint. Constraints that are held by a view don’t constitute an exhaustive list of constraints that affect a view. Every Constraint that affects a view is listed in the size inspector. Constraints that view holds are listed on the left in the document outline. A Constraint between its subview and superview is held by superview. A constraint between two subviews is held by the superview of both

As shown in Figure 10, it prints empty constraint since subView view don’t hold any constrints, as we discussed above Constraints are held that holds constraints that affects a view

Figure 10

Changing the multiplier is not straight forward as compare to changing constraint constant since multiplier is read only , you need to create new constraint with new multiplier and replace with older one

Figure 11

First step is add identifier

Figure 12

As shown in Figure 13 , we did few things

  1. Get constraint that held subview height constraint and delete constrint by using isActive = false . If we deactivate the constraint like this and don’t hold the reference to it , it will be deleted from memory the next time the layout is updated
  2. Then we inject new constraint and activated it
  3. Force layout update using smooth animation technique

You can do other techniques as well , create two height constraint outlet, initially unchecked install button of the one and only change isActive property

Figure 13

Spring Animation

So far we animated constraint properties to get from value A to value B, when you introduce springs, the value will still begin and end where you specify but over the duration of the animation , the value might overshoot value B and oscillate back and forth before finally stop there.

https://www.raywenderlich.com/18411703-uikit-animation/lessons/8

usingSpringWithDamping → The damping ratio for the spring animation as it approaches its quiescent state. To smoothly decelerate the animation without oscillation, use a value of 1. Employ a damping ratio closer to zero to increase oscillation. higher values make the bouncing finish faster and less oscillation as shown in gif 6. 0.2 makes more bouncing and high osccillation as compare to 0.8

initialSpringVelocity → Inital momentum, Intially punch as shown in gif 7, high value give high initial punch as compare to low value

if you specfiy options with spring animations, it do a custom options to match the spring as well

Gif 6
Gif 7

We will use this Gif 3 code , and implement using spring animation

Gif 8

View Transitions

UIKit has a separate animation API to create predefined view transitions, which are quick , animated way to show and hide views or add and remove views from view heiarchy. So we will use this built in animation only when adding, removing, hiding or showing view respective property

As shown in Gif 9 , we used transition animation to show view using trigger isHidden

Gif 9

It’s the more straightforward one.View transitions are predefined, which means they’re somewhat limited, but very powerful and simple to implement. To implement the transition, you have to do one simple thing: pair a transition trigger with a predefined transition.

There are three triggers that should cause a view to transition: Use any of them inside the animation closure on a subview of the specified container view to start the transition animation
isHidden → this one triggers a view’s isHidden property and causes it to disappear from view

.addSubview() → this method adds a subview to a view’s view hierarchy.

removeFromSuperview() → this does the opposite and removes a view from its superview’s view hierarchy.

As for the transitions, there are seven: animation options predefined

  • .transitionFlipFromLeft
  • .transitionFlipFromRight
  • .transitionFlipFromTop
  • .transitionFlipFromBottom
  • .transitionCurlUp
  • .transitionCurlDown
  • .transitionCrossDissolve
https://itnext.io/swift-uiview-lovely-animation-and-transition-d34bd623391f

If you start to type UIView.transition, the XCode autocomplete will give you a couple of options. There are two transition methods . The one we used previously animate a single view . There also a transition method between two views like if you wanted to flip a view around and see a different view on the other side

Let’s play around with this

As shown in Gif 10 , we used hidden = false transition trigger but it is hidden without any animation, Why 😕

No matter which method or animation you choose , the views you want to effect should be wrapped in a separate container view or superview . The container view is the view you pass into the with argument of the transition

Gif 10

As shown in Gif 10 since we gave the viewController as a container view, you can feel the transition effect animation throughout the whole view

Gif 11

As shown in Figure 13 we embedded our subview into a container view and now run thhe application you can see full smoth animation we want

Figure 14

Now we used transitionFlipFromLeft animation option and triggering point is hide and show view

Gif 12

As we talked earlier there also a transition animation method that transitions between two views like if you want to flip a view around and see a different view on the other side . Let’s do it

As shown in Figure 15 , we created container view having two views as a subview, when user tap on toggle button, we will do the transition animation between two views

Figure 15

As shown in Gif 13 we used transition API with only with parameter and it is doing it’s works , there we used different animation option as well

Gif 13

As shown in Gif 14 We did the transition from the greenView to purpleView and viceversa. So we are going to have fromView on the basis of toggle value for the from: parameter and toView for the to: parameter. Let’s have the same 1 seconds for the duration: parameter and let’s use a [.transitionFlipFromTop] for the options: parameter. Have the completion: be nil for now.

The first transition happens as expected, but when you click the button the second time, the compiler hits you with a ⚠ fatal error.

You may have noticed that this variation doesn’t have an animations: closure like the other, and we need the animations: closure to trigger the transition. Beacuse, this variation has some automated processes happening under the hood.

If you check your variables view at the bottom, you will notice that the toView, which in this case is the greenView, is nil.Here’s what happened: the automated transition trigger removed the greenView from the view hierarchy.

In the official Apple documentation, they state that, in this variation, the fromView: is removed from its superview as part of the transition.

Well, that’s all fine, but we can’t just live with this fatal error.

Gif 14

As shown in Gif 15 in options: parameter set,we added another option named .showHideTransitionViews. What this does is simply hide the fromView instead of removing it from the view hierarchy.

Gif 15

As shown in Gif 16 we added Button inside green View, and by default user can’t interact with views while they are being animated. means user can interact with textField at the bottom since it’s not taking part in animation but user can’t interact with button inside green view since it’s taking part in the animation.

Gif 16

By using allowUserInteraction user can interact with views while they are being animated. In this case remember you can interact button when there is an transition between purple view to gree view not vice versa. so in short with allowUserInteraction option you can interact with UI of the view which is going to appear not which is going.

Useful Links

Senior iOS Engineer | HungerStation | Delivery Hero