react-native-navigation的迁移库

TheSidebarController.m 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. // TheSidebarController.m
  2. // TheSidebarController
  3. //
  4. // Copyright (c) 2013 Jon Danao (danao.org | jondanao)
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23. #import "TheSidebarController.h"
  24. static const CGFloat kAnimationDuration = 0.3f;
  25. static const CGFloat kVisibleWidth = 310.0f;
  26. @interface TheSidebarController()
  27. @property (assign, nonatomic) SidebarTransitionStyle selectedTransitionStyle;
  28. @property (assign, nonatomic) Side selectedSide;
  29. @property (strong, nonatomic) UIViewController *selectedSidebarViewController;
  30. @property (strong, nonatomic) NSArray *sidebarAnimations;
  31. @property (strong, nonatomic) UIViewController *contentContainerViewController;
  32. @property (strong, nonatomic) UIViewController *leftSidebarContainerViewController;
  33. @property (strong, nonatomic) UIViewController *rightSidebarContainerViewController;
  34. @property (assign, nonatomic) CATransform3D contentTransform;
  35. - (void)showSidebarViewControllerFromSide:(Side)side withTransitionStyle:(SidebarTransitionStyle)transitionStyle;
  36. - (void)hideSidebarViewController;
  37. - (void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view;
  38. @end
  39. @implementation TheSidebarController
  40. #pragma mark - Designated Initializer
  41. - (id)init
  42. {
  43. return [self initWithContentViewController:nil leftSidebarViewController:nil rightSidebarViewController:nil];
  44. }
  45. - (id)initWithContentViewController:(UIViewController *)contentViewController leftSidebarViewController:(UIViewController *)leftSidebarViewController
  46. {
  47. return [self initWithContentViewController:contentViewController leftSidebarViewController:leftSidebarViewController rightSidebarViewController:nil];
  48. }
  49. - (id)initWithContentViewController:(UIViewController *)contentViewController rightSidebarViewController:(UIViewController *)rightSidebarViewController
  50. {
  51. return [self initWithContentViewController:contentViewController leftSidebarViewController:nil rightSidebarViewController:rightSidebarViewController];
  52. }
  53. - (id)initWithContentViewController:(UIViewController *)contentViewController leftSidebarViewController:(UIViewController *)leftSidebarViewController rightSidebarViewController:(UIViewController *)rightSidebarViewController
  54. {
  55. self = [super init];
  56. if(self)
  57. {
  58. _contentContainerViewController = [[UIViewController alloc] init];
  59. _leftSidebarContainerViewController = [[UIViewController alloc] init];
  60. _rightSidebarContainerViewController = [[UIViewController alloc] init];
  61. _contentContainerViewController.view.backgroundColor = [UIColor clearColor];
  62. _leftSidebarContainerViewController.view.backgroundColor = [UIColor clearColor];
  63. _rightSidebarContainerViewController.view.backgroundColor = [UIColor clearColor];
  64. _contentViewController = contentViewController;
  65. _leftSidebarViewController = leftSidebarViewController;
  66. _rightSidebarViewController = rightSidebarViewController;
  67. _animationDuration = kAnimationDuration;
  68. _visibleWidth = kVisibleWidth;
  69. _sidebarAnimations = @[SIDEBAR_ANIMATIONS];
  70. _sidebarIsPresenting = NO;
  71. }
  72. return self;
  73. }
  74. - (id)initWithContentViewController:(UIViewController *)contentViewController
  75. leftSidebarViewController:(UIViewController *)leftSidebarViewController
  76. storyboardsUseAutoLayout:(BOOL)storyboardsUseAutoLayout
  77. {
  78. self.storyboardsUseAutolayout = storyboardsUseAutoLayout;
  79. return [self initWithContentViewController:contentViewController leftSidebarViewController:leftSidebarViewController];
  80. }
  81. - (id)initWithContentViewController:(UIViewController *)contentViewController
  82. rightSidebarViewController:(UIViewController *)rightSidebarViewController
  83. storyboardsUseAutoLayout:(BOOL)storyboardsUseAutoLayout
  84. {
  85. self.storyboardsUseAutolayout = storyboardsUseAutoLayout;
  86. return [self initWithContentViewController:contentViewController rightSidebarViewController:rightSidebarViewController];
  87. }
  88. - (id)initWithContentViewController:(UIViewController *)contentViewController
  89. leftSidebarViewController:(UIViewController *)leftSidebarViewController
  90. rightSidebarViewController:(UIViewController *)rightSidebarViewController
  91. storyboardsUseAutoLayout:(BOOL)storyboardsUseAutoLayout
  92. {
  93. self.storyboardsUseAutolayout = storyboardsUseAutoLayout;
  94. return [self initWithContentViewController:contentViewController leftSidebarViewController:leftSidebarViewController rightSidebarViewController:rightSidebarViewController];
  95. }
  96. #pragma mark - UIViewController Lifecycle
  97. - (void)viewDidLoad
  98. {
  99. NSAssert(self.contentViewController != nil, @"contentViewController was not set");
  100. [super viewDidLoad];
  101. self.view.translatesAutoresizingMaskIntoConstraints = self.storyboardsUseAutolayout;
  102. self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  103. if(self.leftSidebarViewController)
  104. {
  105. // Parent View Controller
  106. [self addChildViewController:self.leftSidebarContainerViewController];
  107. [self.view addSubview:self.leftSidebarContainerViewController.view];
  108. [self.leftSidebarContainerViewController didMoveToParentViewController:self];
  109. self.leftSidebarContainerViewController.view.translatesAutoresizingMaskIntoConstraints = self.storyboardsUseAutolayout;
  110. self.leftSidebarContainerViewController.view.hidden = YES;
  111. // Child View Controller
  112. [self.leftSidebarContainerViewController addChildViewController:self.leftSidebarViewController];
  113. [self.leftSidebarContainerViewController.view addSubview:self.leftSidebarViewController.view];
  114. [self.leftSidebarViewController didMoveToParentViewController:self.leftSidebarContainerViewController];
  115. }
  116. if(self.rightSidebarViewController)
  117. {
  118. // Parent View Controller
  119. [self addChildViewController:self.rightSidebarContainerViewController];
  120. [self.view addSubview:self.rightSidebarContainerViewController.view];
  121. [self.rightSidebarContainerViewController didMoveToParentViewController:self];
  122. self.rightSidebarContainerViewController.view.translatesAutoresizingMaskIntoConstraints = self.storyboardsUseAutolayout;
  123. self.rightSidebarContainerViewController.view.hidden = YES;
  124. // Child View Controller
  125. [self.rightSidebarContainerViewController addChildViewController:self.rightSidebarViewController];
  126. [self.rightSidebarContainerViewController.view addSubview:self.rightSidebarViewController.view];
  127. [self.rightSidebarViewController didMoveToParentViewController:self.rightSidebarContainerViewController];
  128. }
  129. // Parent View Controller
  130. [self addChildViewController:self.contentContainerViewController];
  131. [self.view addSubview:self.contentContainerViewController.view];
  132. [self.contentContainerViewController didMoveToParentViewController:self];
  133. // Child View Controller
  134. [self.contentContainerViewController addChildViewController:self.contentViewController];
  135. [self.contentContainerViewController.view addSubview:self.contentViewController.view];
  136. [self.contentViewController didMoveToParentViewController:self.contentContainerViewController];
  137. }
  138. - (void)viewWillAppear:(BOOL)animated
  139. {
  140. [super viewWillAppear:animated];
  141. }
  142. - (void)viewWillDisappear:(BOOL)animated
  143. {
  144. [super viewWillDisappear:animated];
  145. }
  146. - (void)viewWillLayoutSubviews
  147. {
  148. [super viewWillLayoutSubviews];
  149. }
  150. - (void)didReceiveMemoryWarning
  151. {
  152. [super didReceiveMemoryWarning];
  153. }
  154. #pragma mark - TheSidebarController Presentation Methods
  155. - (void)dismissSidebarViewController
  156. {
  157. [self hideSidebarViewController];
  158. }
  159. - (void)presentLeftSidebarViewController
  160. {
  161. [self presentLeftSidebarViewControllerWithStyle:SidebarTransitionStyleFacebook];
  162. }
  163. - (void)presentLeftSidebarViewControllerWithStyle:(SidebarTransitionStyle)transitionStyle
  164. {
  165. NSAssert(self.leftSidebarViewController != nil, @"leftSidebarViewController was not set");
  166. [self showSidebarViewControllerFromSide:LeftSide withTransitionStyle:transitionStyle];
  167. }
  168. - (void)presentRightSidebarViewController
  169. {
  170. [self presentRightSidebarViewControllerWithStyle:SidebarTransitionStyleFacebook];
  171. }
  172. - (void)presentRightSidebarViewControllerWithStyle:(SidebarTransitionStyle)transitionStyle
  173. {
  174. NSAssert(self.rightSidebarViewController != nil, @"rightSidebarViewController was not set");
  175. [self showSidebarViewControllerFromSide:RightSide withTransitionStyle:transitionStyle];
  176. }
  177. #pragma mark - TheSidebarController Private Methods
  178. - (void)showSidebarViewControllerFromSide:(Side)side withTransitionStyle:(SidebarTransitionStyle)transitionStyle
  179. {
  180. [[UIApplication sharedApplication] beginIgnoringInteractionEvents];
  181. self.view.autoresizingMask = UIViewAutoresizingNone;
  182. if(side == LeftSide)
  183. {
  184. self.leftSidebarContainerViewController.view.hidden = NO;
  185. self.rightSidebarContainerViewController.view.hidden = YES;
  186. self.selectedSidebarViewController = self.leftSidebarViewController;
  187. self.view.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
  188. }
  189. else if(side == RightSide)
  190. {
  191. self.rightSidebarContainerViewController.view.hidden = NO;
  192. self.leftSidebarContainerViewController.view.hidden = YES;
  193. self.selectedSidebarViewController = self.rightSidebarViewController;
  194. self.view.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight;
  195. }
  196. self.selectedSide = side;
  197. self.selectedTransitionStyle = transitionStyle;
  198. if([self.delegate conformsToProtocol:@protocol(TheSidebarControllerDelegate)] && [self.delegate respondsToSelector:@selector(sidebarController:willShowViewController:)])
  199. {
  200. [self.delegate sidebarController:self willShowViewController:self.selectedSidebarViewController];
  201. }
  202. NSString *animationClassName = self.sidebarAnimations[transitionStyle];
  203. Class animationClass = NSClassFromString(animationClassName);
  204. [animationClass setOverlayContentColor:self.overlayContentColor];
  205. [animationClass animateContentView:self.contentContainerViewController.view
  206. sidebarView:self.selectedSidebarViewController.parentViewController.view
  207. fromSide:self.selectedSide
  208. visibleWidth:self.visibleWidth
  209. duration:self.animationDuration
  210. completion:^(BOOL finished) {
  211. [[UIApplication sharedApplication] endIgnoringInteractionEvents];
  212. self.sidebarIsPresenting = YES;
  213. if([self.delegate conformsToProtocol:@protocol(TheSidebarControllerDelegate)] && [self.delegate respondsToSelector:@selector(sidebarController:didShowViewController:)])
  214. {
  215. [self.delegate sidebarController:self didShowViewController:self.selectedSidebarViewController];
  216. }
  217. }
  218. ];
  219. }
  220. - (void)hideSidebarViewController
  221. {
  222. [[UIApplication sharedApplication] beginIgnoringInteractionEvents];
  223. if([self.delegate conformsToProtocol:@protocol(TheSidebarControllerDelegate)] && [self.delegate respondsToSelector:@selector(sidebarController:willHideViewController:)])
  224. {
  225. [self.delegate sidebarController:self willHideViewController:self.selectedSidebarViewController];
  226. }
  227. NSString *animationClassName = self.sidebarAnimations[self.selectedTransitionStyle];
  228. Class animationClass = NSClassFromString(animationClassName);
  229. [animationClass reverseAnimateContentView:self.contentContainerViewController.view
  230. sidebarView:self.selectedSidebarViewController.parentViewController.view
  231. fromSide:self.selectedSide
  232. visibleWidth:self.visibleWidth
  233. duration:self.animationDuration
  234. completion:^(BOOL finished) {
  235. [[UIApplication sharedApplication] endIgnoringInteractionEvents];
  236. self.sidebarIsPresenting = NO;
  237. if([self.delegate conformsToProtocol:@protocol(TheSidebarControllerDelegate)] && [self.delegate respondsToSelector:@selector(sidebarController:didHideViewController:)])
  238. {
  239. [self.delegate sidebarController:self didHideViewController:self.selectedSidebarViewController];
  240. }
  241. }
  242. ];
  243. }
  244. #pragma mark - UIViewController Setters
  245. - (void)setContentViewController:(UIViewController *)contentViewController
  246. {
  247. // Old View Controller
  248. UIViewController *oldViewController = self.contentViewController;
  249. [oldViewController willMoveToParentViewController:nil];
  250. [oldViewController.view removeFromSuperview];
  251. [oldViewController removeFromParentViewController];
  252. // New View Controller
  253. UIViewController *newViewController = contentViewController;
  254. [self.contentContainerViewController addChildViewController:newViewController];
  255. [self.contentContainerViewController.view addSubview:newViewController.view];
  256. [newViewController didMoveToParentViewController:self.contentContainerViewController];
  257. _contentViewController = newViewController;
  258. }
  259. - (void)setLeftSidebarViewController:(UIViewController *)leftSidebarViewController
  260. {
  261. // Old View Controller
  262. UIViewController *oldViewController = self.leftSidebarViewController;
  263. [oldViewController willMoveToParentViewController:nil];
  264. [oldViewController.view removeFromSuperview];
  265. [oldViewController removeFromParentViewController];
  266. // New View Controller
  267. UIViewController *newViewController = leftSidebarViewController;
  268. [self.leftSidebarContainerViewController addChildViewController:newViewController];
  269. [self.leftSidebarContainerViewController.view addSubview:newViewController.view];
  270. [newViewController didMoveToParentViewController:self.leftSidebarContainerViewController];
  271. _leftSidebarViewController = newViewController;
  272. }
  273. - (void)setRightSidebarViewController:(UIViewController *)rightSidebarViewController
  274. {
  275. // Old View Controller
  276. UIViewController *oldViewController = self.leftSidebarViewController;
  277. [oldViewController willMoveToParentViewController:nil];
  278. [oldViewController.view removeFromSuperview];
  279. [oldViewController removeFromParentViewController];
  280. // New View Controller
  281. UIViewController *newViewController = rightSidebarViewController;
  282. [self.rightSidebarContainerViewController addChildViewController:newViewController];
  283. [self.rightSidebarContainerViewController.view addSubview:newViewController.view];
  284. [newViewController didMoveToParentViewController:self.rightSidebarContainerViewController];
  285. _rightSidebarViewController = newViewController;
  286. }
  287. #pragma mark - Autorotation Delegates
  288. - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
  289. {
  290. [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
  291. if((toInterfaceOrientation == UIInterfaceOrientationPortrait) ||
  292. (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown))
  293. {
  294. NSLog(@"Portrait");
  295. }
  296. else if((toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
  297. (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight))
  298. {
  299. NSLog(@"Landscape");
  300. }
  301. }
  302. #pragma mark - Helpers
  303. - (void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view
  304. {
  305. CGPoint newPoint = CGPointMake(view.bounds.size.width * anchorPoint.x, view.bounds.size.height * anchorPoint.y);
  306. CGPoint oldPoint = CGPointMake(view.bounds.size.width * view.layer.anchorPoint.x, view.bounds.size.height * view.layer.anchorPoint.y);
  307. newPoint = CGPointApplyAffineTransform(newPoint, view.transform);
  308. oldPoint = CGPointApplyAffineTransform(oldPoint, view.transform);
  309. CGPoint position = view.layer.position;
  310. position.x -= oldPoint.x;
  311. position.x += newPoint.x;
  312. position.y -= oldPoint.y;
  313. position.y += newPoint.y;
  314. view.layer.position = position;
  315. view.layer.anchorPoint = anchorPoint;
  316. }
  317. @end
  318. #pragma mark - TheSidebarController Category
  319. @implementation UIViewController(TheSidebarController)
  320. - (TheSidebarController *)sidebarController
  321. {
  322. if([self.parentViewController.parentViewController isKindOfClass:[TheSidebarController class]])
  323. {
  324. return (TheSidebarController *)self.parentViewController.parentViewController;
  325. }
  326. else if([self.parentViewController isKindOfClass:[UINavigationController class]] &&
  327. [self.parentViewController.parentViewController.parentViewController isKindOfClass:[TheSidebarController class]])
  328. {
  329. return (TheSidebarController *)self.parentViewController.parentViewController.parentViewController;
  330. }
  331. return nil;
  332. }
  333. @end