As with Guevara movies, or other apps, you might know that a button-click animation that uses magnification to achieve transitions is now very popular, and the effect is generally as follows
Custom Transitions Animation
First, declare a UIViewControllerAnimatedTransitioning
class that complies with the protocol.
Then implement the two functions in the Protocol
This is used for percent driven interactive transitions, as as a for container controllers, have companion tions that might need to
//return to transition time
-(Nstimeinterval) Transitionduration: (Nullable ID < uiviewcontrollercontexttransitioning>) Transitioncontext;
Movement of Transitions
-(void) Animatetransition: (id <UIViewControllerContextTransitioning>) Transitioncontext;
Both push and pop are animateTransition:
implemented inside, so a parameter is required to indicate whether it is a push or a pop; another parameter represents the transition time
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
typedef enum:nsuinteger {
Animate_push = 0,
animate_pop = 1,
} animate_type;
@interface sftrainsitionanimate:nsobject<uiviewcontrolleranimatedtransitioning>
-(instancetype) Initwithanimatetype: (animate_type) Type andduration: (cgfloat) Dura;
@property (Assign, nonatomic) cgfloat duration;
@property (Assign, nonatomic) Animate_type Type;
@end
So how do you use a new object? Can be passed UINavigationControllerDelegate
in the
-(id<uiviewcontrolleranimatedtransitioning>) Navigationcontroller: (Uinavigationcontroller *) Navigationcontroller animationcontrollerforoperation: (uinavigationcontrolleroperation) operation Fromviewcontroller: (Uiviewcontroller *) Fromvc Toviewcontroller: (Uiviewcontroller *) tovc{
if (operation = Uinavigationcontrolleroperationpush) {
self.animate = [[Sftrainsitionanimate alloc] init];
return self.animate;
} else{return
nil
}
}
Of course, to call this method, you have to UINavigationControllerDelegate
give the delegate to the view controller first.
Self.navigationController.delegate = self;
Look at UIViewControllerAnimatedTransitioning
this protocol again, the method of returning time is not introduced. Focus on
-(void) Animatetransition: (id<uiviewcontrollercontexttransitioning>) transitioncontext{
//Start View Controller
Uiviewcontroller *FROMVC = [Transitioncontext Viewcontrollerforkey:uitransitioncontextfromviewcontrollerkey];
The target view Controller
uiviewcontroller *TOVC = [Transitioncontext viewcontrollerforkey: Uitransitioncontexttoviewcontrollerkey];
On this view realize the jump-rotate drawing
uiview *containview = [Transitioncontext Containerview];
}
As noted above, we can transitionContext
get to start and target control through parameters. And containView
implement the animation we want to implement in this view.
Next is the implementation of the transition animation, the process of the push animation is: Click on the first page of a control, simulate the control and then move to the second interface of the same style control position, and then the second interface to control the position of the center of the spread display.
So now we're going to get the control of the first view through FROMVC in the Protocol method, and make a mirrored view move to the location of the TOVC's target control. Here, I call the UIViewcontroller
Taxonomy Association an object that is used to record controls (not owning relationships).
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
@interface Uiviewcontroller ( sftrainsitionextension)
@property (Assign, nonatomic) cgfloat sf_targetheight;//gray background of the split line height
@property (weak, nonatomic) UIView *sf_targetview;
@end
Generate TargetView Mirrors:
Generate TargetView Mirror image
-(UIView *) Customsnapshofromview: (UIView *) Inputview {//make ' image from '
input view.
uigraphicsbeginimagecontextwithoptions (inputView.bounds.size, NO, 0);
[Inputview.layer Renderincontext:uigraphicsgetcurrentcontext ()];
UIImage *image = Uigraphicsgetimagefromcurrentimagecontext ();
Uigraphicsendimagecontext ();
Create an image view.
UIView *snapshot = [[Uiimageview alloc] initwithimage:image];
Snapshot.layer.masksToBounds = NO;
Snapshot.layer.cornerRadius = 0.0;
Snapshot.layer.shadowOffset = Cgsizemake (0.0, 0.0);
Snapshot.layer.shadowRadius = 5.0;
snapshot.layer.shadowOpacity = 0.4;
return snapshot;
}
Now you can make moving animations:
Starting position CGRect originframe = [Fromvc.sf_targetview convertRect:fromVC.sf_targetView.bounds ToView:fromVC.view];
The view image of the animated motion UIView *customview = [self customSnapshoFromView:fromVC.sf_targetView];
Customview.frame = Originframe;
The moving target position cgrect finishframe = [Tovc.sf_targetview convertRect:toVC.sf_targetView.bounds ToView:toVC.view];
UIView *containview = [Transitioncontext Containerview];
Background view Gray Height CGFloat = cgrectgetmidy (finishframe);
Tovc.sf_targetheight = height;
Background View Gray UIView *backgray = [[UIView alloc] Initwithframe:cgrectmake (0, 0, K_sf_screen_width, k_sf_screen_hight)];
Backgray.backgroundcolor = [Uicolor Lightgraycolor]; Background View white UIView *backwhite = [[UIView alloc] initwithframe:cgrectmake (0, height, k_sf_screen_hight, k_sf_screen_hight-h
Eight)];
Backwhite.backgroundcolor = [Uicolor Whitecolor];
ToVC.view.frame = [Transitioncontext FINALFRAMEFORVIEWCONTROLLER:TOVC];
Note Add order [Containview AddSubview:toVC.view]; [Containview Addsubview:backGray];
[Backgray Addsubview:backwhite];
[Containview Addsubview:customview];
Animation [UIView animatewithduration:_duration/3 animations:^{customview.frame = finishframe;
Customview.transform = Cgaffinetransformmakescale (1.1, 1.1); } completion:^ (BOOL finished) {if (finished) {[UIView animatewithduration:_duration/3 animations:^{customView.tr
Ansform = cgaffinetransformidentity; } completion:^ (BOOL finished) {if (finished) {[UIView animatewithduration:_duration/3 animations:^{CUSTOMVIEW.A
Lpha = 0.0;
} completion:^ (BOOL finished) {if (finished) {[Backgray Removefromsuperview];
[CustomView Removefromsuperview];
[Transitioncontext Completetransition:yes];
}
}];
[Self Addpathanimatewithview:backgray fromPoint:customView.center]; }
}];
After the move is done, show the push interface with a circular diffuser. Can be UIBezierPath
achieved through and CAShapeLayer
. UIBezierPath
represents the path, CAShapeLayer
you can display the area according to the path, so we can look at the effect first with the view of the first interface.
Uibezierpath *path = [Uibezierpath bezierPathWithRect:self.collectionView.bounds];
[Path Appendpath:[uibezierpath bezierPathWithArcCenter:self.collectionView.center radius:50 startangle:0 endangle:2 *m_pi Clockwise:no]];
Cashapelayer *layer = [Cashapelayer layer];
Layer.path = path. Cgpath;
Self.collectionView.layer.mask = layer;
Initializes the path path with four collectionView
edges and then joins a path with a collectionView
center as a dot with a radius of 50, showing the area between the two paths.
And then set the radius size to 200 in the code.
Now, we create an CABasicAnimation
object to complete the diffusion of the animation, the starting position is a circle with a radius of 10, the end position is a circle with a radius of 200.
Uibezierpath *path = [Uibezierpath bezierPathWithRect:self.collectionView.bounds]; [Path Appendpath:[uibezierpath bezierPathWithArcCenter:self.collectionView.center radius:10 startangle:0 endangle:2
*m_pi Clockwise:no]];
Uibezierpath *path2 = [Uibezierpath bezierPathWithRect:self.collectionView.bounds]; [path2 appendpath:[uibezierpath bezierPathWithArcCenter:self.collectionView.center radius:200 startangle:0 endangle
: 2*m_pi Clockwise:no]];
Cashapelayer *layer = [Cashapelayer layer];
Self.collectionView.layer.mask = layer;
Cabasicanimation *pathanimation = [cabasicanimation animationwithkeypath:@ "path"]; Pathanimation.fromvalue = (__bridge id) path.
Cgpath; Pathanimation.tovalue = (__bridge id) path2.
Cgpath;
Pathanimation.duration = 1.0;
Pathanimation.repeatcount = 1;
Pathanimation.removedoncompletion = NO;
Pathanimation.fillmode = Kcafillmodeforwards;
Pathanimation.timingfunction = [Camediatimingfunction functionwithname:kcamediatimingfunctioneaseout]; [Layer AddanimatIon:pathanimation forkey:@ "Pathanimate"];
Now it's time to finish the push transition. Notice that the white part of the circle shows the view at the collectionView
bottom self.view
.
Join collection Animation-(void) Addpathanimatewithview: (UIView *) Toview frompoint: (cgpoint) point{//create path Uibezierpath *path = [
Uibezierpath bezierpathwithrect:cgrectmake (0, 0, K_sf_screen_width, k_sf_screen_hight)]; Create path [path Appendpath:[uibezierpath bezierpathwitharccenter:point radius:0.1 startangle:0 EndAngle:2*M_PI
Clockwise:no]];
CGFloat radius = point.y > 0?K_SF_SCREEN_HIGHT*3/4: k_sf_screen_hight*3/4-point.y;
Uibezierpath *path2 = [Uibezierpath bezierpathwithrect:cgrectmake (0, 0, K_sf_screen_width, K_SF_SCREEN_HIGHT)]; [path2 appendpath:[uibezierpath bezierpathwitharccenter:point Radius:radius startangle:0 EndAngle:2*M_PI:
NO]];
Cashapelayer *shapelayer = [Cashapelayer layer]; Shapelayer.path = path.
Cgpath;
ToView.layer.mask = Shapelayer;
Cabasicanimation *pathanimation = [cabasicanimation animationwithkeypath:@ "path"]; Pathanimation.fromvalue = _type = = Animate_push? (__bridge ID) path. Cgpath: (__bridge ID) path2.
Cgpath; Pathanimation.tovalue = _tyPE = = Animate_push? (__bridge ID) path2. Cgpath: (__bridge ID) path.
Cgpath;
Pathanimation.duration = _DURATION/3;
Pathanimation.repeatcount = 1;
Pathanimation.removedoncompletion = NO;
Pathanimation.fillmode = Kcafillmodeforwards;
Pathanimation.timingfunction = [Camediatimingfunction functionwithname:kcamediatimingfunctioneaseout];
[Shapelayer addanimation:pathanimation forkey:@ "Pathanimate"]; }
Pop animation is actually the same as push, here is not said.
Well, the above is the entire content of this article, I hope the content of this article for everyone's study or work can bring some help, if you have questions you can message exchange.