實現控制器之間的切換:(實現彈跳的效果:)html
先實現一個自定義的相似的modal present的效果,與普通效果不一樣的是,咱們但願modalVC出現的時候不要那麼乏味的就簡單從底部出現,而是帶有一個彈性效果:ios
ViewController的實現:mvc
1 // 2 // ViewController.m 3 // ViewController切換 4 // 5 // Created by 思 彭 on 16/3/29. 6 // Copyright © 2016年 combanc. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "ModalViewController.h" 11 #import "BouncePresentAnimation.h" 12 13 14 15 @interface ViewController ()<ModalViewControllerDelegate,UIViewControllerTransitioningDelegate> 16 17 @property (nonatomic, strong) BouncePresentAnimation *presentAnimation; 18 19 20 @end 21 22 @implementation ViewController 23 24 25 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 26 { 27 self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 28 if (self) { 29 30 _presentAnimation = [BouncePresentAnimation new]; 31 32 } 33 return self; 34 } 35 36 37 38 - (void)viewDidLoad { 39 [super viewDidLoad]; 40 self.view.backgroundColor = [UIColor lightGrayColor]; 41 42 UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 43 button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0); 44 button.backgroundColor = [UIColor redColor]; 45 [button setTitle:@"Dismiss me" forState:UIControlStateNormal]; 46 [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; 47 [self.view addSubview:button]; 48 49 50 } 51 52 53 // 按鈕點擊觸發方法 54 55 -(void) buttonClicked:(id)sender 56 { 57 ModalViewController *mvc = [[ModalViewController alloc] init]; 58 59 mvc.delegate = self; 60 mvc.transitioningDelegate = self; 61 62 //模態到ModalViewController 63 [self presentViewController:mvc animated:YES completion:nil]; 64 } 65 66 67 //實現協議方法 68 69 -(void)modalViewControllerDidClickedDismissButton:(ModalViewController *)viewController 70 { 71 [self dismissViewControllerAnimated:YES completion:nil]; 72 } 73 74 75 76 - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source 77 { 78 return self.presentAnimation; 79 } 80 81 82 83 84 - (void)didReceiveMemoryWarning { 85 [super didReceiveMemoryWarning]; 86 // Dispose of any resources that can be recreated. 87 } 88 89 @end
ModalViewController的實現:app
1 #import <UIKit/UIKit.h> 2 3 @class ModalViewController; 4 5 @protocol ModalViewControllerDelegate<NSObject> 6 7 8 -(void) modalViewControllerDidClickedDismissButton:(ModalViewController *)viewController; 9 10 11 @end 12 13 14 @interface ModalViewController : UIViewController 15 16 @property (nonatomic, weak) id<ModalViewControllerDelegate> delegate; 17 18 @end
1 // 2 // ModalViewController.m 3 // ViewController切換 4 // 5 // Created by 思 彭 on 16/3/29. 6 // Copyright © 2016年 combanc. All rights reserved. 7 // 8 9 #import "ModalViewController.h" 10 11 @implementation ModalViewController 12 13 14 - (void)viewDidLoad{ 15 16 [super viewDidLoad]; 17 18 // Do any additional setup after loading the view. 19 self.view.backgroundColor = [UIColor grayColor]; 20 21 UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 22 button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0); 23 button.backgroundColor = [UIColor greenColor]; 24 [button setTitle:@"Dismiss me" forState:UIControlStateNormal]; 25 [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; 26 [self.view addSubview:button]; 27 28 } 29 30 // 按鈕點擊觸發方法 31 32 -(void) buttonClicked:(id)sender 33 { 34 if (self.delegate && [self.delegate respondsToSelector:@selector(modalViewControllerDidClickedDismissButton:)]) { 35 [self.delegate modalViewControllerDidClickedDismissButton:self]; 36 } 37 } 38 39 40 41 @end
BouncePresentAnimation的代碼實現:框架
1 #import <Foundation/Foundation.h> 2 #import <UIKit/UIKit.h> 3 4 5 // 在遵照協議UIViewControllerAnimatedTransitioning記得導入UIKit框架 6 7 @interface BouncePresentAnimation : NSObject<UIViewControllerAnimatedTransitioning> 8 9 10 @end
1 // 2 // BouncePresentAnimation.m 3 // ViewController切換 4 // 5 // Created by 思 彭 on 16/3/29. 6 // Copyright © 2016年 combanc. All rights reserved. 7 // 8 9 #import "BouncePresentAnimation.h" 10 11 @implementation BouncePresentAnimation 12 13 14 15 #pragma mark - UIViewControllerAnimatedTransitioning代理 16 17 - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{ 18 19 return .6f; 20 21 22 } 23 24 25 - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{ 26 27 // 1. Get controllers from transition context 28 UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 29 30 // 2. Set init frame for toVC 31 CGRect screenBounds = [[UIScreen mainScreen] bounds]; 32 CGRect finalFrame = [transitionContext finalFrameForViewController:toVC]; 33 toVC.view.frame = CGRectOffset(finalFrame, 0, screenBounds.size.height); 34 35 // 3. Add toVC's view to containerView 36 UIView *containerView = [transitionContext containerView]; 37 [containerView addSubview:toVC.view]; 38 39 // 4. Do animate now 40 NSTimeInterval duration = [self transitionDuration:transitionContext]; 41 [UIView animateWithDuration:duration 42 delay:0.0 43 usingSpringWithDamping:0.6 44 initialSpringVelocity:0.0 45 options:UIViewAnimationOptionCurveLinear 46 animations:^{ 47 toVC.view.frame = finalFrame; 48 } completion:^(BOOL finished) { 49 // 5. Tell context that we completed. 50 [transitionContext completeTransition:YES]; 51 }]; 52 53 54 } 55 56 57 @end
解釋一下這個實現:iview
1.咱們首先須要獲得參與切換的兩個ViewController的信息,使用context的方法拿到它們的參照;ide
2.對於要呈現的VC,咱們但願它從屏幕下方出現,所以將初始位置設置到屏幕下邊緣;動畫
3.將view添加到containerView中;ui
4.開始動畫。這裏的動畫時間長度和切換時間長度一致,都爲0.8s。usingSpringWithDamping的UIView動畫API是iOS7新加入的,描述了一個模擬彈簧動做的動畫曲線,咱們在這裏只作使用,更多信息能夠參看相關文檔;(順便多說一句,iOS7中對UIView動畫添加了一個很方便的Category,UIViewKeyframeAnimations。使用其中方法能夠爲UIView動畫添加關鍵幀動畫)atom
5.在動畫結束後咱們必須向context報告VC切換完成,是否成功(在這裏的動畫切換中,沒有失敗的可能性,所以直接pass一個YES過去)。系統在接收到這個消息後,將對VC狀態進行維護。