Ios_20_weibo Custom Animation switching navigation Controller
Final effect:
AnimatedNavigationController. h
/// AnimatedNavigationController. h // 20 _ handsome guy no Weibo /// Created by beyond on 14-8-10. // Copyright (c) 2014 com. beyond. all rights reserved. // inherits from the navigation controller, but has one more function. You can listen to gestures and perform animation switching # import
@ Interface AnimatedNavigationController: UINavigationController @ end
AnimatedNavigationController. m
/// AnimatedNavigationController. m // 20 _ handsome guy no Weibo /// Created by beyond on 14-8-10. // Copyright (c) 2014 com. beyond. all rights reserved. // # import "AnimatedNavigationController. h "// used # import
# Import "BeyondViewController. h "@ interface AnimatedNavigationController () {// screen UIImageView * _ screenshotImgView; // The above black translucent mask UIView * _ coverView; // store all NSMutableArray * _ screenshotImgs ;} @ end @ implementation AnimatedNavigationController-(void) viewDidLoad {[super viewDidLoad]; // 1. Create a Pan gesture reader and bind it to the listening method pai* panGestureRec = [UIPanGestureRecognizer alloc] initWithTarget: self action: @ Selector (panGestureRec :)]; // Add the Pan gesture reader [self. view addGestureRecognizer: panGestureRec]; // 2. the created ImageView _ screenshotImgView = [[UIImageView alloc] init]; // the frame of the app is the frame _ screenshotImgView with the height of the status bar removed. frame = [UIScreen mainScreen]. applicationFrame; // (0 20; 320 460); // 3. create the black translucent mask _ coverView = [[UIView alloc] init]; // The masked frame is the frame _ coverView. frame = _ screenshotImgView. frame; // The mask is black _ coverView. backgroundColor = [UIColor blackColor]; // 4. store all array initialization _ screenshotImgs = [NSMutableArray array];} // rewrite the push method. Capture the image-(void) pushViewController :( UIViewController *) viewController animated :( BOOL) before pushing) animated {// if (self. viewControllers. count> = 1) {// call the custom method and use the context [self screenShot];} // to call the push method of the parent class [super pushViewController: viewController ani Mated: YES];} // use the context and crop the image using the specified region. The template code-(void) screenShot {// view to be taken, beyondViewController * beyondVC = (BeyondViewController *) self. view. window. rootViewController; // The total size of the background image CGSize = beyondVC. view. frame. size; // enable the context. After parameters are used, the source image (YES 0.0 high quality) uigraphicsbeginimagecontextwitexceptions (size, YES, 0.0) is captured ); // The range of the rectangle to crop CGRect rect = CGRectMake (0,-20.8, siz E. width, size. height + 20); // Note: renderInContext after iOS7: replaced by [beyondVC. view drawViewHierarchyInRect: rect afterScreenUpdates: NO]; // obtain the UIImage * snapshot = screenshot () from the context; // Add the captured image to the Image array [_ screenshotImgs addObject: snapshot]; // do not forget to end the context (remove the graph context at the top of the stack based on the current Bitmap) UIGraphicsEndImageContext ();} // listen to the gesture method, if there is a gesture, it will execute-(void) PanGestureRec :( UIPanGestureRecognizer *) panGestureRec {// if the currently displayed controller is already a root controller, you do not need to perform any switching animation and directly return if (self. topViewController = self. viewControllers [0]) return; // you can call this operation to determine the phase switch (panGestureRec) of the pan gesture. state) {case UIGestureRecognizerStateBegan: // start the drag phase [self dragBegin]; break; case UIGestureRecognizerStateEnded: // end the drag phase [self dragEnd]; break; default: // In the drag phase [self dragging: panGestureRec]; break; }}# Pragma mark start dragging, adding images and masks-(void) dragBegin {// focus, each time you start the Pan gesture, add imageview and cover to window [self. view. window insertSubview: _ screenshotImgView atIndex: 0]; [self. view. window insertSubview: _ coverView aboveSubview: _ screenshotImgView]; // also, the imgView displays the last (latest) _ screenshotImgView in the array. image = [_ screenshotImgs lastObject];} // The default initial scale to be scaled # define kDefaultScale 0.6 // The default initial transparency of the mask to be transparent (all black) # define kDef AultAlpha 1.0 // when the drag distance accounts for 3/4 of the total width of the screen, the imageview is completely displayed, and the cover completely disappears # define kTargetTranslateScale 0.75 # pragma mark is being dragged, the essence of the animation effect, scaling and transparency change-(void) dragging :( UIPanGestureRecognizer *) pan {// get the displacement CGFloat offsetX = [pan translationInView: self. view]. x; // only drag to the right. Drag To the left. if (offsetX <0) offsetX = 0; // move the entire view to self. view. transform = CGAffineTransformMakeTranslation (offsetX, 0); // calculate the current finger drag The ratio of displacement to the total width of the screen. When the ratio reaches 3/4, the imageview is completely displayed, and the double currentTranslateScaleX = offsetX/self. view. frame. size. width; // scale the imageview. The default ratio is + (current equilibrium ratio/Target Equilibrium Ratio) * (1-default ratio) double scale = kDefaultScale + (currentTranslateScaleX/kTargetTranslateScale) * (1-kdefascale scale); // if (scale> 1) scale = 1; _ screenshotImgView, the original size is reached. transform = CGAffineTransformMakeScale (scale, scale); // opacity Change until it is reduced to 0 to make the mask completely transparent. Default ratio-(current equilibrium ratio/Target Equilibrium Ratio) * default ratio double alpha = kDefaultAlpha-(currentTranslateScaleX/kTargetTranslateScale) * kDefaultAlpha; _ coverView. alpha = alpha ;}# pragma mark: Click it to finish dragging. The distance between the drag is determined and the image and mask are removed from the parent control.-(void) dragEnd {// retrieve the moving distance CGFloat translateX = self. view. transform. tx; // retrieve the width CGFloat width = self. view. frame. size. width; if (translateX <= width * 0.5) {// if the distance from the finger to the screen is less than half, move it to the left (Bounce Back) [UIView animateWithDuration: 0.3 animations: ^ {// important ~~ Let the right-shifted view return to the back position. You only need to clear the transform to implement self. view. transform = CGAffineTransformIdentity; // restore the imageView size to the default scale _ screenshotImgView. transform = CGAffineTransformMakeScale (kdefascale scale, kdefascale scale); // restore the covered transparency to the default alpha 1.0 _ coverView. alpha = kDefaultAlpha;} completion: ^ (BOOL finished) {// important. After the animation is completed, remember to remove two views each time. The next time you start dragging, then add [_ screenshotImgView removeFromSuperview]; [_ coverView removeFromSupervi Ew];} else {// If the finger is more than half the screen distance, move [UIView animateWithDuration: 0.3 animations: ^ {// Let the right-shifted view be completely moved to the far right of the screen. Remember to clear the transform self of the view after the end. view. transform = CGAffineTransformMakeTranslation (width, 0); // set imageView to 1 _ screenshotImgView. transform = CGAffineTransformMakeScale (1, 1); // change the covering alpha to 0 to completely transparent _ coverView. alpha = 0;} completion: ^ (BOOL finished) {// important ~~ Let the right-shifted view be completely moved to the far right of the screen. After the end, remember to clear the transform of the view. Otherwise, a problem will occur when the drag starts again, because the transform of the view is not reset to self. view. transform = CGAffineTransformIdentity; // remove two views. The next time you start dragging, add [_ screenshotImgView removeFromSuperview]; [_ coverView removeFromSuperview]; // perform the normal Pop operation: remove the stack top controller to make the real previous controller the stack top controller of the navigation controller [self popViewControllerAnimated: NO]; // important ~ Remember this time, you can remove the last useless [_ screenshotImgs removeLastObject] ;}}}@ end in the array.