Deep learning iOS7 Custom navigation transitions animation _ios

Source: Internet
Author: User

Prior to IOS7, developers who want to customize the navigation controller to push into the view of the transition animation, usually only through subclasses Uinavigationcontroller or write their own animation code to cover the corresponding method, now iOS7 for the developer to bring the gospel, Apple introduced a large number of new APIs, giving developers high degrees of freedom, when dealing with UIView animations managed by Uiviewcontroller, these APIs are easy to use, scalable and very easy to customize:

    • A new animated block method for UIView
    • New uiviewcontrolleranimatedtransitioning protocol and the concept of the animation controller
    • Interaction controllers and Transition coordinators
    • New animation-oriented Assistant API (Easy method)

A new animated block method for UIView
IOS4 's release brings a powerful block approach that can be easily satisfied with blocks when writing UIView animations, but in some cases we have to use the core Animation directly. Fortunately, Apple added 2 new block-based approaches to iOS7, so we rarely have to use the core animation directly.
1. Key frame animation
IOS7 encapsulates a set of APIs for UIView, making it easy to get the same effect as the cakeyframeanimation in the core animation framework.

 [UIView animatekeyframeswithduration:duration delay:delay 
options:options animations:^{ 
[UIView addkeyframewithrelativestarttime:0.0 
relativeduration:0.5 animations:^{ 
//First frame to execute animation 
}]; 
[UIView addkeyframewithrelativestarttime:0.5 
relativeduration:0.5 animations:^{ 
//second frame animation to execute 
}]; 
completion:^ (BOOL finished) { 
//code block to execute after animation 
}]; 

The newly introduced relationship between Animatekeyframeswithduration and cakeyframeanimation can be compared to animatewithduration and Cabasicanimation, All we need to do is add each frame animation to the block method and pass in the relative start time and execution time of the animation throughout the process (duration specifically refers to the percentage of the animation's execution time as a whole process). At the same time, you can use multiple keyframes in one animation, just use Addkeyframe to add all keyframes to the animation stack in turn.

The following is a simple example: in the example application, I use the keyframe block to exit the modal view controller.

[UIView addkeyframewithrelativestarttime:0.0 relativeduration:0.15 animations:^{//Clockwise rotation 90 degrees Snapshot.transform = CGAf 
Finetransformmakerotation (M_PI *-1.5); 
}]; [UIView addkeyframewithrelativestarttime:0.15 relativeduration:0.10 animations:^{//180 Degree snapshot.transform = 
Cgaffinetransformmakerotation (M_PI * 1.0); 
}]; [UIView addkeyframewithrelativestarttime:0.25 relativeduration:0.20 animations:^{//Pendulum over midpoint, 225 degrees Snapshot.transform = 
Cgaffinetransformmakerotation (M_PI * 1.3); 
}]; [UIView addkeyframewithrelativestarttime:0.45 relativeduration:0.20 animations:^{/back again, 140 degrees Snapshot.transform = 
Cgaffinetransformmakerotation (M_PI * 0.8); 
}]; 
[UIView addkeyframewithrelativestarttime:0.65 relativeduration:0.35 animations:^{///final step, view fades and disappears 
Cgaffinetransform shift = Cgaffinetransformmaketranslation (180.0, 0.0); 
Cgaffinetransform rotate = cgaffinetransformmakerotation (M_PI * 0.3); 
Snapshot.transform = Cgaffinetransformconcat (shift, rotate); _coverview.alphA = 0.0; 
 }];

The view seemed to rotate clockwise in the lower left corner, under the traction of gravity, and swung at the lowest point, and finally fell off.

2. Spring Animation
IOS7 's new introduction of another block method allows you to easily integrate the elastic effects of the real physical world into the view animation. Apple has been advising developers to do as much as possible in the real world of animation--When a view slides, it can be like a spring, slightly stretched, and then bounced back to the correct position. Using the new Spring Animation API to achieve this effect is much simpler than ever.

[UIView animatewithduration:duration delay:delay 
usingspringwithdamping:damping initialSpringVelocity: Velocity 
options:options animations:^{// 
here write animation related code 
} completion:^ (BOOL finished) { 
//code blocks executed after animation 
}]; 

Here are some physical concepts: The damping parameter represents the elastic damping, and as the damping value gets closer to 0.0, the elastic effect of the animation becomes more and more obvious, and if the damping value is set to 1.0, the view animation will not have an elastic effect-the view slides directly to 0 and stops immediately, There will be no spring-type stretching effect.

The velocity parameter represents the elastic correction speed, which represents the speed at which the view is restored when bouncing, for example, if the maximum distance that the view is stretched in the animation is 200 pixels, and you want the view to be restored at 100 pixels per second, the velocity value is set to 0.5. (Translator: We suggest that you look at the source code, the code damping set to 0.8 is not obvious enough, you can damping to 0.1, and then slowly adjust the velocity to see the effect)

In the sample application, I animate the modal view controller from the bottom of the screen, set the elastic damping to 0.8, the elastic correction speed to 1.0, and see the view as it runs out of the 15 pixel distance and then slowly return to its original position. If I set the elastic damping to 0.6 or smaller, the view will go higher, and it will continue to bounce back before it returns to its original position. (that is, stop to rebound more and more, elastic effect is more and more obvious) it should be noted that the elastic animation is not confused with the uikit dynamic effects engine. Elastic animation is a standard UIView animation API that only provides a limited number of real-world physical effects.

Custom Uiviewcontroller Animation of transitions
Now let's look at a good thing. Apple has not only introduced new animation APIs for developers, but has also expanded its scope of application. When pushing through the Uiviewcontroller management view, you can easily customize the following transitions animation:

Uiviewcontroller
Presentviewcontroller
Uitabbarcontroller
Setselectedviewcontroller
setSelectedIndex
Uinavigationcontroller
Pushviewcontroller
Popviewcontroller
setviewcontrollers

In the sample application, I created a series of transition animations that used the new spring animation and Keyframe block method I explained earlier, and now let's look at how you can use the new API to customize the above transitions animation.
1, Core concept: Animation controller
So, how do you use a custom animation without affecting other properties of the view? Apple offers a new protocol: uiviewcontrolleranimatedtransitioning, we can write custom animation code in the Protocol method. The Apple Developer's document says the object that implements this protocol is the animation controller. &NBSP
Because we use the syntax of the protocol, custom animation code can be flexibly placed where you want it. You can create a class that is designed to manage animations, or you can let Uiviewcontroller implement uiviewcontrolleranimatedtransitioning interfaces. Because you need to implement a series of different animations, you choose to create a class for each animation. Next, create the generic parent class--baseanimation for these animated classes, which defines some common properties and helper methods.
Let's take a look at the first animation, which has a simple scaling effect when you push the view with Uinavigationcontroller.

-(void) Animatetransition: (ID) transitioncontext {//Get container view reference UIView *containerview = [Transitioncontext containerview 
]; Uiviewcontroller *fromviewcontroller = [Transitioncontext viewcontrollerforkey: 
Uitransitioncontextfromviewcontrollerkey]; Uiviewcontroller *toviewcontroller = [Transitioncontext viewcontrollerforkey: 
Uitransitioncontexttoviewcontrollerkey]; if (Self.type = = animationtypepresent) {//insert ' to ' view, initial scaling value is 0.0 toViewController.view.transform = Cgaffinetransformmakes 
Cale (0.0, 0.0); 
[Containerview InsertSubview:toViewController.view AboveSubview:fromViewController.view]; 
Scale the to view for the desired effect [UIView animatewithduration:[self Transitionduration:transitioncontext] animations:^{ 
ToViewController.view.transform = Cgaffinetransformmakescale (1.0, 1.0); 
} completion:^ (BOOL finished) {[Transitioncontext completetransition:yes]; 
}]; else if (Self.type = = Animationtypedismiss) {//insert ' to ' view [Containerview InsertSubview:toViewController.view BELOWSUBV Iew:fromviewcOntroller.view]; 
Narrow the from view until it disappears [UIView animatewithduration:[self Transitionduration:transitioncontext] animations:^{ 
FromViewController.view.transform = Cgaffinetransformmakescale (0.0, 0.0); 
} completion:^ (BOOL finished) {[Transitioncontext completetransition:yes]; 
}]; 
}-(Nstimeinterval) Transitionduration: (ID) transitioncontext {return 0.4; 
 }

Any object that conforms to the Uiviewcontrolleranimatedtransitioning protocol needs to implement Animatetransition: and Transitionduration: two methods. You can also choose to implement the @optional method animationended: It is automatically called by the system after the animation is completed, which is equivalent to completion block, very convenient.
In animatetransition: You need to deal with the following processes:
1. Insert the "to" view into the container view
2. Move the "to" and "from" views to where you want them
3. Finally, never forget to call Completetransition when the animation is complete: method
The methods in the Uiviewcontrolleranimatedtransitioning protocol all carry a parameter: Transitioncontext, which is a system-level object that conforms to the Uiview-controllercontexttransitioning protocol, we can obtain the necessary information from this object to control the animation of the transitions, including the following:

Obviously, Apple has helped developers do most of the annoying details, and the only thing we need to do is to define the animation's initial state and termination status and adjust to its own satisfying results. Finally, I'm going to say two more things. Important Notes on Transitioncontext:

1. The method for obtaining a frame may return cgrectzero--if the system cannot determine what the value of the frame is. For example, if you use a custom modal view controller
To eject the animation, the system cannot determine its finalframe at the end.
2. If the view controller has been removed from the screen, the method to obtain the frame will also return Cgrectzero. For example, after the transition animation for the navigation controller ends, an attempt is made to get the finalframe of the From view.
You do not have to manually remove the "from" View, Transitioncontext will automatically help you complete.
3. If you need to use transitioncontext elsewhere in your application, you can safely use the animation controller to keep a transitioncontext reference.
Apply the animation controller to the transition animation.

Now that we've developed the animation controller, the last thing we need to do is apply it to the transition animation: we need to do something about the Uiviewcontroller that manages the transition animation.

In general, we just need to make uiviewcontroller conform to the Uiviewcontroller-transitioningdelegate protocol, Write Animationcontroller-forpresentedcontroller and Animationcontrollerfordismissedcontroller methods. In my sample application, I set up a property to let the animation controller know whether the view is currently being pushed or rolled out:

 -(ID) 
animationcontrollerforpresentedcontroller: (Uiviewcontroller 
*) presented Presentingcontroller: ( Uiviewcontroller 
*) presenting Sourcecontroller: (Uiviewcontroller *) source { 
Modalanimationcontroller.type = Animationtypepresent; 
return modalanimationcontroller; 
} 
-(ID) 
animationcontrollerfordismissedcontroller: (Uiviewcontroller 
*) dismissed { 
Modalanimationcontroller.type = Animationtypedismiss; 
return modalanimationcontroller; 
} 

Then, when the modal view controller is pushed, we set the Modalpresentationstyle to Uimodalpresentationfullscreen or Uimodalpresentationcustom. We must also set an object that conforms to the Uiviewcontrollertransitioningdelegate protocol to its transitioningdelegate, Generally, Uiviewcontroller is pushed into the modal view controller.

Optionsviewcontroller *modal = [[Optionsviewcontroller alloc] 
initwithnibname:@ "Optionsviewcontroller" bundle:[ NSBundle 
Mainbundle]]; 
Modal.transitioningdelegate = self; 
Modal.modalpresentationstyle = Uimodalpresentationcustom; 
[Self presentviewcontroller:modal animated:yes 
Completion:nil]; 

If you need to apply an animation controller to a Uinavigationcontroller transition animation, We need to use a new method in the Uinavigationcontrollerdelegate protocol: animationcontrollerforoperation. For any custom navigation transition animation, the navigation bar will have a fade-and-fade animation process. Similarly, for Uitabbarcontroller, a new approach to using the Uitabbarcontrollerdelegate protocol-- Animationcontroller-fortransitionfromviewcontroller.

Define the interaction for the Transitions animation
In IOS7, Apple uses interactive pop-up gestures everywhere, and Apple provides developers with a set of tools that can be applied to the view switching process in a few simple steps. We can return an interaction controller through the appropriate delegate method:

    • Uinavigationcontroller
    • Interactioncontrollerforanimationcontroller
    • Uitabbarcontroller
    • Interactioncontrollerforanimationcontroller
    • Uiviewcontroller
    • Interactioncontrollerforpresentation
    • Interactioncontrollerfordismissal

The only thing to note here is that these methods do not work without custom transitions animations. For example, you must get a valid animation controller from Animationcontrollerforoperation, Uinavigationcontroller will call interactioncontroller-
foranimationcontroller--even if you are not using an animation controller in transition interactions.

Second, the interactive controller is very flexible and has a strong scalability. Although I use gesture detection in the sample application to control the interaction, you can do it in a way other than gestures. You can design whatever effects you want to interact with the transitions.

Interaction controller: The simplest way to implement this is to create an interactive controller in two ways. The first and simplest one is the use of uipercentdriveninteractivetransition.

 @interface uipercentdriveninteractivetransition:nsobject 
 
@property (readonly) cgfloat duration; 
@property (readonly) cgfloat PercentComplete; 
@property (nonatomic,assign) cgfloat completionspeed; 
@property (nonatomic,assign) uiviewanimationcurve 
completioncurve; 
-(void) Updateinteractivetransition: (cgfloat) PercentComplete; 
-(void) cancelinteractivetransition; 
-(void) finishinteractivetransition; 

This class specifically implements the Uiviewcontrollerinteractivetransitioning protocol, which we can use to easily add a custom interaction to the animation controller. As long as you add gestures (or other interactions) to the target view and call Updateinteractivetransition: The incoming animation time is a percentage of the entire process. Also, remember to call finishinteractivetransition after the interaction completes: call Cancel-interactivetransition when the interaction is canceled:. The following example shows how to apply a kneading gesture to a transition animation:

-(void) Handlepinch: (Uipinchgesturerecognizer *) Pinch {cgfloat scale = Pinch.scale; 
Switch (pinch.state) {case Uigesturerecognizerstatebegan: {_startscale = scale; 
Self.interactive = YES; 
[Self.navigationcontroller Popviewcontrolleranimated:yes]; 
Break 
Case uigesturerecognizerstatechanged: {cgfloat percent = (1.0-scale/_startscale); 
[Self updateinteractivetransition: (Percent < 0.0)? 
0.0:percent]; 
Break 
Case uigesturerecognizerstateended: {cgfloat percent = (1.0-scale/_startscale); 
BOOL cancelled = ([pinch velocity] < 5.0 && percent <= 0.3); 
if (cancelled) [self cancelinteractivetransition]; 
else [self finishinteractivetransition]; 
Break 
Case uigesturerecognizerstatecancelled: {cgfloat percent = (1.0-scale/_startscale); 
BOOL cancelled = ([pinch velocity] < 5.0 && percent <= 0.3); 
if (cancelled) [self cancelinteractivetransition]; 
else [self finishinteractivetransition]; 
Break 
 } 
} 
}

When you inherit the Uipercentdriveninteractivetransition class, the system automatically invokes the animatetransition of the animation controller in the interactive process: method, The animation effect is displayed in real time according to the PercentComplete parameters you pass. After the interaction completes, it also automatically invokes the Animatetransition: The method reverts to the normal state, and once the interaction completes, we can change the Completionspeed and Completioncurve properties to modify some of the other styles.

Interactive controllers: By customizing the way
If you need to drill down to the details of the uipercentdriveninteractivetransition process animation, you don't have to inherit the class, Instead, use the Uiviewcontroller-interactivetransitioning protocol. This protocol is similar to uiviewcontroller-animatedtransitioning, where we can control all the details about the transitions animation. In this agreement we need to complete the following steps:

1. Implement Startinteractivetransition: Method for initializing a special session animation.
2. Get a reference to the Transitioncontext object (If you inherited uipercentdriveninteractivetransition, you can see that it automatically helps us complete this step, so we have to get the object manually).
3. As before, invoke Updateinteractivetransition:,cancelinteractivetransition and finishinteractivetransition in appropriate cases ( For navigation controllers, you also need to show or hide the navigation bar in the completion method.
4. Still remember to call transitioncompleted when you are finished:.

Here's what I've done with the same animations I've done with my custom interactive controller, still using kneading gestures to control the transition animations.

 -(void) Startinteractivetransition: (ID) transitioncontext {//Get reference to Transitioncontext object _context = Transitioncontext; 
Gets the container view reference UIView *containerview = [Transitioncontext Containerview]; Uiviewcontroller *fromviewcontroller = [Transitioncontext viewcontrollerforkey: 
Uitransitioncontextfromviewcontrollerkey]; Uiviewcontroller *toviewcontroller = [Transitioncontext viewcontrollerforkey: 
Uitransitioncontexttoviewcontrollerkey]; 
Insert "to" view ToViewController.view.frame = [Transitioncontext Finalframeforviewcontroller:toviewcontroller]; 
[Containerview InsertSubview:toViewController.view BelowSubview:fromViewController.view]; 
Keep a reference to a small view of _transitioningview = Fromviewcontroller.view; 
}-(void) Updatewithpercent: (cgfloat) percent {CGFloat scale = FABSF (percent-1.0); 
_transitioningview.transform = Cgaffinetransformmakescale (scale, scale); 
[_context updateinteractivetransition:percent]; }-(void) End: (BOOL) cancelled {if (cancelled) {[UIView Animatewithduration:_compLetionspeed animations:^{_transitioningview.transform = Cgaffinetransformmakescale (1.0, 1.0); 
} completion:^ (BOOL finished) {[_context cancelinteractivetransition]; 
[_context Completetransition:no]; 
}]; else {[UIView animatewithduration:_completionspeed animations:^{_transitioningview.transform = CGAffineTransformMa 
Kescale (0.0, 0.0); 
} completion:^ (BOOL finished) {[_context finishinteractivetransition]; 
[_context Completetransition:yes]; 
}]; 
 } 
}

You can have the animation controller implement both Uiviewcontrollerinteractive-transitioning and uiviewcontrolleranimatedtransitioning (as in the example program), So that all of the code is placed in a class. You can also divide the interaction controller and the animation controller into two classes--the beauty of the syntax of the protocol is that you can easily achieve the best solution that meets your needs.

More tips
Select whether to animate in the block
Developers may experience a situation in which we need to have some views not animated in a string of beautifully animated effects, creating a sound and dynamic effect. Before the animation block method is introduced, we can use the setanimationsenabled method between [UIView beginanimations] and [UIView commitanimations] to set which animations do not need to be executed. In Ios7sdk, Apple offers developers a new way to write animations that don't need to be executed in block:

 [UIView performwithoutanimation:^{ 
//Ensure no animations are performed 
}]; 

You can execute this code at any time to control animations that do not need to be executed.

Navigation transitions Animation for a collection view
You may be very familiar with Uicollectionview's setlayout:animated: method. In IOS7, when the navigation controller pushes into the collection view controller, the setlayout:animated: method is automatically invoked if the Uselayout-tolayoutnavigationtransitions property is turned on. Therefore, when you push a collection view controller, you only need to set this property, the navigation controller can automatically perform the animation, and you manually to the collection view call setlayout:animated method effect.

 Collectionviewcontroller *VC = [[Collectionviewcontroller 
alloc] initwithcollectionviewlayout:flowlayout]; 
Vc.title = @ "Mini Apples"; 
Vc.uselayouttolayoutnavigationtransitions = YES; 
[Self.navigationcontroller PUSHVIEWCONTROLLER:VC 
Animated:yes]; 

Transitions Animation Scheduler
There is also a very useful API that can help the view controller manage Transitions animations: the Uiviewcontrollertransitioncoordinator protocol. In IOS7, each view controller (including Uinavigationcontroller and Uitabbarcontroller, of course) has a transitioncoordinator attribute, This property provides a series of powerful tools for moving animations, first let's look at Animatealongsidetransition: methods.

 [Self.transitioncoordinator 
animatealongsidetransition:^ (ID
rdinatorcontext> context) { 
// The animation to be performed 
} 
completion:^ (ID context 
) { 
//code block after animation end 
}]; 

In this way, we can execute some other animations in parallel in the transition animation, and the context parameters are similar to the transitioncontext parameters of the Uiviewcontrollercontexttransitioning protocol mentioned earlier. From this parameter we can get some important information about the transition process, including container view and transition effects. Apple even allows developers to not pass in the context parameter, passing only the block that is executed after completion. So make a bold attempt to use it.

For interactive transitions, the state of the view may change during the transition process, so the Notifywheninteractionendsusingblock: method is particularly useful-it can be used to manage view state. In an interactive transition, the Viewwillappear: method may be invoked when a view controller is pushed in, but the viewdidappear that should be invoked by common sense will not necessarily, since the user may be able to cancel the interaction at any time (for example, in the previous example, pinch to half and revert to the original).

Thus, if we do not want to modify view state in this case, we can use this method to recover the changes to the views (using the Uiviewcontrollertransitioncoordinatorcontext iscancelled property).

 [Self.transitioncoordinator 
notifywheninteractionendsusingblock:^ (id
sitioncoordinatorcontext> Context) { 
///The code block of the line after the animation is finished 
}]; 
 

Screen shot
before IOS7, getting a UIView snapshot has the following steps: First create a uigraphics image context, and then render the layer of the view into the context to get an image and finally close the image context. and displays the image in Uiimageview. Now all we need is one line of code to complete the above steps:

 
 

This method makes a copy of the UIView, which is especially handy if we want the view to save its current appearance before the animation is executed, for later use (the view in the animation may be obscured by the quilt view or some other changes occur).

The Afterupdates parameter indicates whether the snapshot will be fetched after all effects are applied to the view. For example, if the argument is no, immediately takes a snapshot of the current state of the view, whereas the following code can only get a blank snapshot:

[View Snapshotviewafterscreenupdates:yes]; 
[View setalpha:0.0]; 

Since we set the Afterupdates parameter to Yes, and the transparency value of the view is set to 0, the method will take a snapshot after the setting is applied to the view, so that the screen is empty. The other is ... You can take snapshots again ... Continue the snapshot ...
Apple has added a new API for developers to create and customize animations in IOS7. The IOS7 SDK not only introduces powerful animation blocks and many easy to use methods, but also radically changes the way you customize animations for views.

The above is the entire content of this article, I hope to help you learn.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.