Autolayout constraint animation (what a cute trick!)

Autolayout constraint animation (what a cute trick!)

  • Original article: Animating Autolayout Constraints
  • Author: @kharrison
  • Translator: CocoaChina--It's hard to come up with a name (CC Forum ID)

Written in late spring of 2015: It has been five days since my last post. After reading the feedback from my colleagues, I reworked this code to avoid adding or removing constraints at runtime. Instead of these clunky Java-like methods, I started to dynamically change the priority of the yellow and blue view constraints. Super simple and super efficient.

Before autoLayout, if you want to move a view, the frame will send its two younger brothers, origin or size, to yell at you, "Try to move me!" Of course, frame, bounds, and center are all properties of UIView, so when you really move them, UIView will not give up. So you know why users can see a series of animations, UIView wants to cut you.

If you start using AutoLayout, you'll soon find that you don't have to deal with frames (or bounds or center) yourself. You can ask constraints to do it. This article uses a simple example to show you how to use constraints to do something. Well, to be more precise, to create a simple animation effect.

challenge

For simplicity, we only use two views. A yellow view (hereinafter referred to as yellow view) and a blue view (hereinafter referred to as blue view). In "normal" mode, we only see the yellow view. In "colorful" mode, both blue and yellow views can be seen.

view…

"Hey! Why do I only see pornographic pictures?"

"Is it really okay to call it colorful when there are only two colors?"

"You should leave a seed!"

Oops, sorry, I only paid attention to the yellow image. In "colorful" mode, we see two images, the yellow image and the blue image. These two views should fill the entire screen, except for the edges of the device and the frame occupied by the switch. The gif below is what we want to achieve.

The blueprint should slide out on the right, and the yellow image should fill the screen accordingly...

Setting Basic Constraints

At first, I dragged out the view in IB and added constraints. At this time, both views were visible.

The yellow image has five constraints: the left side relative to the parent view, the right side relative to the blueprint, the top side relative to the switch, the bottom side relative to the parent view, and the constraint that it is equal to the blueprint width.

The constraints of the blueprint and the yellow image are similar, except that the blueprint is spaced on the right relative to the parent view.

Non-required constraint priority

When only the yellow image is visible (which is great), we need to add another constraint, which is the spacing constraint on its right side relative to the parent view. If I add this constraint above, it will conflict with the "right relative to blueprint constraint" because they both have priority 1000. In order to avoid conflicts and move the blueprint, we can change the priority of the constraint that is spacing the yellow blueprint.

The priority of a required constraint is UILayoutPriorityRequired (1000). You cannot change the priority of a required constraint at runtime. A constraint with a priority lower than UILayoutPriorityRequired is an optional or non-required constraint, like this, and you can change it as long as you don't set the priority to UILayoutPriorityRequired.

So first, let's lower the priority of the right side of the blueprint relative to the parent view constraint to 750.

Then we add a constraint to the right side of the yellow image relative to its parent view (as mentioned above), and set the priority to 750.

Drag out the constraints!

In order to change the right constraint of the blueprint at runtime we have to drag this constraint into the code first. You can also drag any constraint out like this. (Just like linking the control to the code, select the constraint, press Ctrl and drag)

  1. @property (weak, nonatomic) IBOutlet NSLayoutConstraint *blueViewConstraint;

To make sure we push the blueprint off the screen, we also have to adjust the spacing constraint between the yellow image and the blueprint, so we also incorporate this constraint into the code.

  1. @property (weak, nonatomic) IBOutlet NSLayoutConstraint *viewSpacingContraint;

Update Constraints

  1. - ( void )updateConstraintsForMode {
  2. if (self.modeSwitch.isOn) {
  3. self.viewSpacingContraint.constant = 8.0 ;
  4. self.blueViewConstraint.priority = UILayoutPriorityDefaultHigh+ 1 ;
  5. } else {
  6. self.viewSpacingContraint.constant = self.view.frame.size.width;
  7. self.blueViewConstraint.priority = UILayoutPriorityDefaultHigh- 1 ;
  8. }
  9. }

Now it's easy to write a method to set the desired priority of the Blueprint constraint based on the mode switch.

In the storyboard, we also set the priority of the right constraint of the yellow image relative to the parent view to UILayoutPriorityDefaultHigh (750). To make the blueprint visible, we need to set the priority of the right constraint of the blueprint higher than 750, and when hiding the blueprint, we have to set it lower.

Pay attention! Look at the blackboard! We need to set a larger value for the interval of the yellow blueprint (I use the screen width here) to ensure that the blueprint pushes out of the right edge.

We should also configure constraints when the view first loads. It is not a good idea to favor one over the other.

  1. - ( void )viewDidLoad {
  2. // ...  
  3. [self updateConstraintsForMode];
  4. }

Get moving!

Now everything is ready, we just need to flick the mode switch. Eh? Gently, eh? Oh, sorry, I forgot to write the event code for the switch. Apple's Auto Layout Guide describes the basic method of autoLayout animation. The recommended code is as follows:

  1. [containerView layoutIfNeeded];
  2. [UIView animateWithDuration: 1.0 animations:^{
  3. // Make all constraint changes here  
  4. [containerView layoutIfNeeded];
  5. }];

The two calls to layoutIfNeeded force the pending operations to complete, and then capture the frame changes in an animation block.

(Translator's note: This reminds me of an answer on Zhihu: What kind of shitty code have you seen in company projects?)

  1. if (m_doc->isModified() == true )
  2. {
  3. for ( int i = 0 ; i < 100 ; i++)
  4. {
  5. save(); //Save the document for 100 times to ensure it has been saved successfully.  
  6. }
  7. }

Using the above method in our chestnut, it looks like this:

  1. - (IBAction)enableMode:(UISwitch *)sender {
  2. NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
  3. [defaults setBool:sender.isOn forKey:modeUserDefaultKey];
  4. [defaults synchronize];
  5.     
  6. [self.view layoutIfNeeded];
  7. [UIView animateWithDuration:1.0 animations:^{
  8. [self updateConstraintsForMode];
  9. [self.view layoutIfNeeded];
  10. }];
  11. }

Summarize

The code is here, click me.

<<:  Liu Minghao analyzes JD Finance's Zeus security defense platform

>>:  What? You pronounced YouTube and App wrongly.

Recommend

You think the sea is blue? Actually, your eyes deceive you.

Is the ocean really blue? In a study published in...

Four ways to attract traffic to Zhihu in 2019!

Now more and more people trust Zhihu and not Baid...

Can you believe it? Mosquitoes can actually help with vaccinations!

In order to enable the body to acquire immunity t...

Humans used light to "trick" AI, but the result was...

As we all know, artificial intelligence (AI) is v...

How to acquire 800,000 customers at low cost through growth strategies?

Introduction to the disassembly content: Disassem...

Counterpoint: Global cellular IoT module shipments fell 2% in Q3 2023

According to the latest data from Counterpoint, g...

Don’t know where to start with CPC optimization? This is how Ready Player One plays!

“ Information flow ”, “oCPC”, and “creativity”, w...

A major reshuffle of the top 15 automakers in November 2017

According to the latest data released by the Chin...

Build a house on the moon! "Lunar soil bricks" are here

The building bricks we use in our daily lives gen...