Note: I wrote two articles for transition animations:
The first: [IOS] Transition animation of the simple imitation system, the main analysis of the system simple animation implementation principle, as well as the interpretation of the coordinate system, absolute coordinate system, relative coordinate system, coordinate system transformation knowledge, for the second chapter of the Reserve Theory Foundation. Finally, the file preview animation on Mac is implemented.
Second: [IOS] Advanced simulation of the transition animation Airbnb, mainly based on the first theory to achieve a complex interface transition, including entry and exit animation series. Finally, the implementation of this animation is decoupled from the current interface, and encapsulated as a universal (other similar interface also applicable) tool class.
These two articles will show you how to achieve a similar transition animation on the Airbnb home page, and most importantly, you'll learn how to analyze similar animations and know how to do it. The GitHub address is here.
If you do not read the first article, then I suggest you go to the first article, because if there is no basis for the first article, this article is still more difficult to understand. Well, let's go now. All right, you ready? Now let's start with the second article. This article is based primarily on the first theory to achieve complex interface transitions, including the concatenation of entry and exit animations. Finally, the implementation of this animation is decoupled from the current interface, and encapsulated as a universal (other similar interface also applicable) tool class. 01. The architecture of this interface
Let's start by analyzing the architecture of this interface. The window is a uitableviewcontroller that can scroll up and down, and each uitableviewcell has a uicollectionview that can slide right and left, in each Uicollectionviewcell On the layout of a cover picture and other elements. Very mainstream layout, that's roughly the case, right?
02. Based on the first article, how should we divide the structure of this animation?
How should the above animation be analyzed? What? I think I heard a classmate saying, "Too soon?" Well, then I'll slow down a little bit, and you'll look at it carefully.
Do you see it? You haven't seen it yet? Just see them moving? Is there a feeling of light?
Let's see another picture. If we have a larger brain hole, not the interface structure, we think of the interface as a plane, then we can follow this picture to divide the animation structure.
As you can see, the animation is actually divided into three parts, Upanimationpart + Centreanimationpart + downanimationpart,upanimationpart and Downanimationpart Animations can be grouped into one category, they simply move up or down. The focus is on the middle Centreanimationpart, which has some differences from the rest.
Centreanimationpart, each picture is animated as a single individual, not the entire module in the middle. Why is it? Because each picture is finally filled with a control at the top of the next screen. That's too hard to understand? This means that if you get the middle area as a whole to animate, then you will get the middle of the image area is covered, and the right side of the orange image you will not be able to get, this time when the user clicked on the right side of the image of the left half of the picture, you will not achieve the middle area of the animation.
If you understand what I'm saying, then you'll understand the subtle differences between the two pictures.
The two pictures above, the animation structure of the second picture is correct.
After dividing the animation structure, you should have a discovering feeling. Have you ever felt like the system animations that were implemented in the first article? I hope you can summarize the core of the problem from this analysis and training: The hardest part is our understanding, not the realization.
03. Attention Points
Now that you have all the ideas, then write the code quickly? ... Wait, do you really have the idea? Can you tell me what it is?
It's okay to learn things so quickly. It is not consolation, it is the truth of the matter.
Let's look at two points of knowledge and one point of attention.
Circular reference of 3.1.Block
Perhaps you have been vaguely aware that this animation will inevitably use the block, block has a very difficult "circular reference", you may still do not understand what is a "citation ring", said that the problem may have to write another article is enough, so I do not intend to clarify this issue here.
So my advice to you is that you are not sure if you are unsure of where the circular reference is going to be, and you are writing:
__weak typeof(self) weakSelf = self; self.aBlock = ^{ __strong typeof(weakSelf) strongSelf = weakSelf; if (!strongSelf) return; // 其它代码 ... }
Why do you write this?
The issue of relieving circular references. __weak is a weak reference and will not have the self reference counter +1. _strong will weakself reference counter +1 to maintain the holding of weakself, but Strongself is a local variable, after this block of code, STRONGSELF will automatically release, so the possibility of the circular reference is lifted.
Prevent the application from collapsing. if (!strongself) return; We assume a very common situation when self has been released, the block is moved, and then go to a nil zombie object, for example, a property of self inserted into a dictionary or something, this time to insert empty elements into the dictionary, will naturally cause the application to collapse, with this line of code, There would be no such situation.
3.2. Recycling Pool
Every day we use the UITableView why the performance is so good, a large part of the reason is due to the recycling pool this design idea.
The design idea of recycling pool can be summarized as follows:
- When an object is used, it is taken from the Reusepool, and if there is a cache in the Reusepool, the cache is removed, returned to the user, and then removed from the Reusepool. If not in Reusepool, create a new object and return it to the consumer.
- When an object has moved out of view (or does not need to be used), it is added to the reusepool to wait for another loop.
Based on this goal of high performance, we should create a reusepool for our animated Uiimageview instances.
3.3. How do I test the correct frame of my own calculation?
Calculating the frame and migrating the frame is a very tangled thing, and do not know whether they are correct, if not, it will cause animation confusion. But if the final transfer of the painting back to the frame, it is necessary to repeatedly check which frame is wrong. It hurts like a egg.
So I'll give you a suggestion. Is that you add a placeholder view on this frame to see if you're finished with a frame. For example, add a red View to the screen like this to check the frame right:
[[UIView alloc]init];redView.backgroundColor = [UIColor redColor];redView.frame = YourFrame;[self.view.window addSubview:redView];
3.4. How do I find the Uiimageview that shows the cover picture on Uicollectionviewcell?
This requires you to bind a tag to the uiimageview when you use it so that I can get the uiimageview.
04. How do you implement your ideas?
Let us summarize the above analysis to see if we can analyze the concrete implementation of our ideas.
4.1. Animated Material
4.1.1, when the user clicks the moment, we should first put the current window (note, Windows window) to do, spare.
4.1.2, we need to have a tool that gives this tool the clip's point and clipping type, which will help us tailor a picture to the style we want. Let's say we just need the upper half, or the lower part.
4.1.3, we need to the user click on the Uicollectionviewcell above the Frame of the picture moved to the window coordinates, and then calculate the location of the point to be cropped, and finally the window screen and this point passed in to cut, get our animation needs to do the picture.
4.1.4, now do the animation needs of the elements we already have Upanimationpart and Downanimationpart need the picture, now only the Centreanimationpart need the visible Cell above the picture, this we pass Uicollectionview's visiablecells can get it. In this way, the animated material is ready.
4.2. Animation start position
The starting position of the animation should be the easiest part of the animation.
The starting position of 4.2.1 and Upanimationpart should be above the Y-coordinate of the image of the Cell that clicked. If you specify Uptailory as the Y-coordinate of the image that clicks the Cell, then:
CGRect upAnimationImageViewFrame_start = CGRectMake(0, 0, JPScreenWidth, upTailorY);
4.2.2, similarly, if the downtailory is specified as the bottom of the picture that clicked the Cell (the height of the Y-coordinate is added). So, the starting position of the Downanimationpart should be:
CGRect downAnimationImageViewFrame_start = CGRectMake(0, downTailorY, JPScreenWidth, JPScreenHeight - downTailorY);
The starting position of the picture of the Cell in the middle of the 4.2.3 can be directly obtained through the coordinate system migration. After that, we have all the parts of the animation starting point, so we can add uiimageview to the window later.
4.3. Animation end Position
The first article said that the test of the mathematics of the part of the finally, or a little excitement. In fact, it is very simple, you can see a picture to know:
4.3.1, upanimationpart the end of the location is easy, simple to you can directly write it out:
CGRect upAnimationImageViewFrame_end = CGRectMake(0, -upTailorY, JPScreenWidth, upTailorY);
The end position of 4.3.2 and Downanimationpart is:
CGRect downAnimationImageViewFrame_end = CGRectMake(0, JPScreenHeight, JPScreenWidth, JPScreenHeight - downTailorY);
4.3.3, Centreanimationpart will be a little bit more complex, in fact, should be divided into three kinds of situations. See details:
4.3.3.1, tapimage the clicked picture, its end position should be easy to determine, is to fill the top of the screen:
There's no objection to that? The other two categories need to be positioned to refer to its location.
CGRect tapAnimationImageViewFrame_end = CGRectMake(0, 0, JPScreenWidth, JPScreenWidth*2.0/3.0);
4.3.3.2, Tapimage_left. Take a look at this picture below, you must understand, right? The initial width of the tapimage we know that the left side of the picture and tapimage we can figure out, the screen width we also know, now using the cross-phase multiplication, we can quickly get the value of the red box, that is, we want to end position X coordinate.
4.3.3.3, Tapimage_right. I'm not going to go into this. Similar to the situation above.
05. Code Implementation
I do not intend to paste the code in the article, a, length has been very long, and then paste the code, will let some "too long do not see" the students feel pressure is great. Secondly, the code is already on GitHub, and it's more comfortable to see the code in Xcode. And I put Keynote in the same place.
06. Decoupling and Extracting tool classes
If you write in this way, you will find that all the code is concentrated in one method, resulting in three hundred or four hundred lines of code for this method, very bloated. and the entry and exit animation incredibly coupled together, to decouple, to draw the tool class and feel the impossible. This time should have a kind of courage to break the wrist: "Lao Tzu must take you to the tool" determination. With this determination, the rest is to find a way.
This animation has a lot of parameters, so for which is necessary, have to choose. That is to try to design the API for the tool class.
/*! * \~chinese * @prama indexPath 用户选中的那个UICollectionViewCell的 indexPath. * @prama collectionView 用户选中的那个UICollectionViewCell的 UICollectionView. * @prama viewController 动画之前窗口上显示的 viewController. * @prama presentViewController 动画完成之后要在窗口上显示的 viewController. * @prama afterPresentedBlock 动画完成之后要在 presentViewController 做的事情. * * @return JPContainIDBlock 关闭动画的 block. */
For decoupling, my understanding is that there should be a "try not to be coupled" consciousness before writing the code first. If the project is particularly in a hurry, you can temporarily ignore the coupling, these very deep things may require long-term accumulation and the overall view of the project, these can wait for the weekend or between the project when there is time to carefully ponder.
There is also the perseverance of the will, sometimes to a class decoupling time may be more than you spend time to write again, more. But, to sum up, what are we thinking about when we have more time? Are these times spent on a higher level of transaction than the realization of functionality?
07. About Jpnavigationcontroller
The animation was finally rendered, and it was inseparable from a frame I had before. It is also said that if there is no basis for my previous frame, then the animation of the closed section will not be implemented.
Specifically reflected in the interception of pop gestures.
#pragma mark --------------------------------------------------#pragma mark JPNavigationControllerDelegate-(BOOL)jp_navigationControllerShouldPushRight{ [self backBtnClick:nil]; return NO;}
It can be broadly outlined that when a user starts a pop, our current controller receives an inquiry from the proxy method asking if the pop behavior needs to continue. In this animation we urgently need to receive this inquiry, but do not need to continue the pop behavior, so we return No.
If you want to understand the implementation of this framework, you can look at these three articles:
First article: [Ios]uinavigationcontroller Full-screen pop for each controller custom Uinavigationbar. This article is mainly about how to implement a custom navigation bar, all the ideas and implementation are jntian.
The second article: [Ios]uinavigationcontroller Full-screen pop for each controller to add the bottom linkage view. This article describes how to add a custom "bottom linkage view" based on an existing custom navigation bar. All the ideas and implementations are my own.
The third article: [Ios]uinavigationcontroller Full-screen pop for the controller to add a left slide push. This time it will tell you how to implement the left slide push to the bound controller with the push animation.
or visit my GitHub jpnavigationcontroller.
08.GitHub Address
The GitHub address is here.
Thanks for sharing
Advanced emulation of [IOS] transition animations Airbnb