UIViewController+CWLateralSlide.m 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. //
  2. // UIViewController+CWLateralSlide.m
  3. // ViewControllerTransition
  4. //
  5. // Created by chavez on 2017/6/29.
  6. // Copyright © 2017年 chavez. All rights reserved.
  7. //
  8. #import "UIViewController+CWLateralSlide.h"
  9. #import "CWInteractiveTransition.h"
  10. #import "CWDrawerTransition.h"
  11. #import <objc/runtime.h>
  12. @implementation UIViewController (CWLateralSlide)
  13. // 显示默认抽屉
  14. - (void)cw_showDefaultDrawerViewController:(UIViewController *)viewController {
  15. [self cw_showDrawerViewController:viewController animationType:CWDrawerAnimationTypeDefault configuration:nil];
  16. }
  17. // 显示抽屉
  18. - (void)cw_showDrawerViewController:(UIViewController *)viewController animationType:(CWDrawerAnimationType)animationType configuration:(CWLateralSlideConfiguration *)configuration {
  19. if (viewController == nil) return;
  20. if (configuration == nil)
  21. configuration = [CWLateralSlideConfiguration defaultConfiguration];
  22. CWLateralSlideAnimator *animator = objc_getAssociatedObject(self, &CWLateralSlideAnimatorKey);
  23. if (animator == nil) {
  24. animator = [CWLateralSlideAnimator lateralSlideAnimatorWithConfiguration:configuration];
  25. objc_setAssociatedObject(viewController, &CWLateralSlideAnimatorKey, animator, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  26. }
  27. viewController.transitioningDelegate = animator;
  28. objc_setAssociatedObject(viewController, &CWLateralSlideDirectionKey, @(configuration.direction), OBJC_ASSOCIATION_ASSIGN);
  29. CWInteractiveTransition *interactiveHidden = [CWInteractiveTransition interactiveWithTransitiontype:CWDrawerTransitiontypeHidden];
  30. [interactiveHidden setValue:viewController forKey:@"weakVC"];
  31. [interactiveHidden setValue:@(configuration.direction) forKey:@"direction"];
  32. [animator setValue:interactiveHidden forKey:@"interactiveHidden"];
  33. animator.configuration = configuration;
  34. animator.animationType = animationType;
  35. if (@available(iOS 13.0, *)) {
  36. viewController.modalPresentationStyle = UIModalPresentationFullScreen;
  37. }
  38. [self presentViewController:viewController animated:YES completion:nil];
  39. }
  40. // 注册抽屉手势
  41. - (void)cw_registerShowIntractiveWithEdgeGesture:(BOOL)openEdgeGesture transitionDirectionAutoBlock:(void(^)(CWDrawerTransitionDirection direction))transitionDirectionAutoBlock {
  42. CWLateralSlideAnimator *animator = [CWLateralSlideAnimator lateralSlideAnimatorWithConfiguration:nil];
  43. self.transitioningDelegate = animator;
  44. objc_setAssociatedObject(self, &CWLateralSlideAnimatorKey, animator, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  45. CWInteractiveTransition *interactiveShow = [CWInteractiveTransition interactiveWithTransitiontype:CWDrawerTransitiontypeShow];
  46. [interactiveShow setValue:@(openEdgeGesture) forKey:@"openEdgeGesture"];
  47. [interactiveShow setValue:transitionDirectionAutoBlock forKey:@"transitionDirectionAutoBlock"];
  48. [interactiveShow addPanGestureForViewController:self];
  49. [animator setValue:interactiveShow forKey:@"interactiveShow"];
  50. }
  51. // 抽屉内push界面
  52. - (void)cw_pushViewController:(UIViewController *)viewController{
  53. [self cw_pushViewController:viewController drewerHiddenDuration:0];
  54. }
  55. - (void)cw_pushViewController:(UIViewController *)vc drewerHiddenDuration:(NSTimeInterval)duration {
  56. CWLateralSlideAnimator *animator = (CWLateralSlideAnimator *)self.transitioningDelegate;
  57. animator.configuration.HiddenAnimDuration = duration > 0 ? duration : animator.configuration.HiddenAnimDuration;
  58. UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
  59. UINavigationController *nav;
  60. NSString *TransitionType = kCATransitionPush;
  61. if ([rootVC isKindOfClass:[UITabBarController class]]) {
  62. UITabBarController *tabbar = (UITabBarController *)rootVC;
  63. NSInteger index = tabbar.selectedIndex;
  64. nav = tabbar.childViewControllers[index];
  65. }else if ([rootVC isKindOfClass:[UINavigationController class]]) {
  66. if (animator.animationType == CWDrawerAnimationTypeDefault) TransitionType = kCATransitionFade;
  67. nav = (UINavigationController *)rootVC;
  68. }else {
  69. NSLog(@"This no UINavigationController...");
  70. return;
  71. }
  72. NSNumber *direction = objc_getAssociatedObject(self, &CWLateralSlideDirectionKey);
  73. NSString *subType = direction.integerValue ? kCATransitionFromLeft : kCATransitionFromRight;
  74. CATransition *transition = [CATransition animation];
  75. transition.duration = 0.20f;
  76. transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
  77. transition.type = TransitionType;
  78. transition.subtype = subType;
  79. [nav.view.layer addAnimation:transition forKey:nil];
  80. [self dismissViewControllerAnimated:YES completion:nil];
  81. [nav pushViewController:vc animated:NO];
  82. }
  83. // 抽屉内present页面
  84. - (void)cw_presentViewController:(UIViewController *)viewController {
  85. [self cw_presentViewController:viewController drewerHidden:NO];
  86. }
  87. - (void)cw_presentViewController:(UIViewController *)vc drewerHidden:(BOOL)hidden {
  88. UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
  89. UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
  90. vc.view.frame = CGRectMake(0, kCWSCREENHEIGHT, kCWSCREENWIDTH, kCWSCREENHEIGHT);
  91. vc.view.tag = 5201314;
  92. [keyWindow addSubview:vc.view];
  93. [UIView animateWithDuration:0.25 animations:^{
  94. vc.view.frame = CGRectMake(0, 0, kCWSCREENWIDTH, kCWSCREENHEIGHT);
  95. } completion:^(BOOL finished) {
  96. // 强引用,不然会被释放
  97. [rootVC addChildViewController:vc];
  98. if (hidden) {
  99. [self dismissViewControllerAnimated:YES completion:nil];
  100. }
  101. }];
  102. }
  103. - (void)cw_dismissViewController {
  104. if (self.view.tag != 5201314 && self.parentViewController.view.tag != 5201314) {
  105. NSLog(@"只有通过cw_presentViewController显示的控制器才能调用此方法...");
  106. return;
  107. }
  108. UIViewController *weakSelf = self;
  109. if (self.parentViewController.view.tag == 5201314) {
  110. weakSelf = self.parentViewController;
  111. }
  112. weakSelf.edgesForExtendedLayout = UIRectEdgeNone;
  113. [UIView animateWithDuration:0.25 animations:^{
  114. weakSelf.view.frame = CGRectMake(0, kCWSCREENHEIGHT, kCWSCREENWIDTH, kCWSCREENHEIGHT);
  115. } completion:^(BOOL finished) {
  116. [weakSelf.view removeFromSuperview];
  117. [weakSelf removeFromParentViewController];
  118. }];
  119. }
  120. @end