YPTabBarController.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. //
  2. // YPTabBarController.m
  3. // YPTabBarController
  4. //
  5. // Created by 喻平 on 15/8/11.
  6. // Copyright (c) 2015年 YPTabBarController. All rights reserved.
  7. //
  8. #import "YPTabBarController.h"
  9. #import "JXHomeScrollView.h"
  10. #import <objc/runtime.h>
  11. #define TAB_BAR_HEIGHT 50
  12. @interface YPTabBarController () {
  13. BOOL _didViewAppeared;
  14. }
  15. @property (nonatomic, strong) JXHomeScrollView *scrollView;
  16. @property (nonatomic, assign) BOOL contentScrollEnabled;
  17. @property (nonatomic, assign) BOOL contentSwitchAnimated;
  18. @property (nonatomic, weak) UIView *line_View;
  19. @end
  20. @implementation YPTabBarController
  21. - (instancetype)init {
  22. self = [super init];
  23. if (self) {
  24. [self awakeFromNib];
  25. }
  26. return self;
  27. }
  28. - (instancetype)initWithCoder:(NSCoder *)coder {
  29. self = [super initWithCoder:coder];
  30. if (self) {
  31. }
  32. return self;
  33. }
  34. - (void)viewWillAppear:(BOOL)animated{
  35. [super viewWillAppear:animated];
  36. [super viewWillAppear:animated];
  37. if (!_didViewAppeared) {
  38. self.tabBar.selectedItemIndex = 0;
  39. _didViewAppeared = YES;
  40. }
  41. [g_notify addObserver:self selector:@selector(tabarFrame:) name:@"tabbarFrame" object:nil];
  42. }
  43. - (void)tabarFrame:(NSNotification *)note{
  44. NSDictionary *noteDict=note.userInfo;
  45. if ([noteDict[@"title"] intValue]==1) {
  46. CGSize screenSize = [UIScreen mainScreen].bounds.size;
  47. CGFloat navigationAndStatusBarHeight = 0;
  48. if (self.navigationController) {
  49. navigationAndStatusBarHeight = self.navigationController.navigationBar.frame.size.height + 20;
  50. }
  51. self.tabBar.frame = CGRectMake(0,
  52. screenSize.height - TAB_BAR_HEIGHT - 0-(JX_SCREEN_HEIGHT>=812?90:65),
  53. screenSize.width,
  54. (JX_SCREEN_HEIGHT>=812?60:50));
  55. UIView *line_View =[[UIView alloc]initWithFrame:CGRectMake(0, screenSize.height - 50 - 0-(JX_SCREEN_HEIGHT>=812?90:65), JX_SCREEN_WIDTH,1)];
  56. line_View.backgroundColor=kRGBColor(246, 246, 246);
  57. //[self.view addSubview:line_View];
  58. self.line_View=line_View;
  59. [self.line_View setHidden:NO];
  60. self.contentViewFrame = CGRectMake(0, 0, screenSize.width,
  61. screenSize.height - TAB_BAR_HEIGHT - navigationAndStatusBarHeight-(JX_SCREEN_HEIGHT>=812?90:65));
  62. }else{
  63. CGSize screenSize = [UIScreen mainScreen].bounds.size;
  64. CGFloat navigationAndStatusBarHeight = 0;
  65. if (self.navigationController) {
  66. navigationAndStatusBarHeight = self.navigationController.navigationBar.frame.size.height + 20;
  67. }
  68. self.tabBar.frame = CGRectMake(0, screenSize.height, screenSize.width,0);
  69. self.contentViewFrame = CGRectMake(0, 0, JX_SCREEN_WIDTH,JX_SCREEN_HEIGHT - 50-0);
  70. [self.line_View setHidden:YES];
  71. [self.line_View removeFromSuperview];
  72. // [self.tabBar removeFromSuperview];
  73. }
  74. }
  75. - (void)awakeFromNib {
  76. [super awakeFromNib];
  77. _selectedControllerIndex = -1;
  78. _tabBar = [[YPTabBar alloc] init];
  79. _tabBar.delegate = self;
  80. [self.view addSubview:self.tabBar];
  81. }
  82. - (void)viewDidLoad {
  83. [super viewDidLoad];
  84. // 设置默认的tabBar frame
  85. CGSize screenSize = [UIScreen mainScreen].bounds.size;
  86. CGFloat navigationAndStatusBarHeight = 0;
  87. if (self.navigationController) {
  88. navigationAndStatusBarHeight = self.navigationController.navigationBar.frame.size.height + 20;
  89. }
  90. //
  91. [self.view addSubview:self.tabBar];
  92. // 设置默认的contentViewFrame
  93. self.contentViewFrame = CGRectMake(0,0,screenSize.width,
  94. screenSize.height - TAB_BAR_HEIGHT-(JX_SCREEN_HEIGHT>=812?90:65));
  95. self.view.clipsToBounds = YES;
  96. self.view.backgroundColor = [UIColor whiteColor];
  97. }
  98. - (void)setViewControllers:(NSArray *)viewControllers {
  99. for (UIViewController *controller in self.viewControllers) {
  100. [controller removeFromParentViewController];
  101. [controller.view removeFromSuperview];
  102. }
  103. _viewControllers = [viewControllers copy];
  104. [_viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
  105. [self addChildViewController:obj];
  106. }];
  107. NSMutableArray *items = [NSMutableArray array];
  108. for (UIViewController *controller in _viewControllers) {
  109. YPTabItem *item = [[YPTabItem alloc] init];
  110. item.image = controller.yp_tabItemImage;
  111. item.selectedImage = controller.yp_tabItemSelectedImage;
  112. item.title = controller.yp_tabItemTitle;
  113. [items addObject:item];
  114. }
  115. self.tabBar.items = items;
  116. if (_didViewAppeared) {
  117. // NSLog(@"asdfasdf");
  118. _selectedControllerIndex = -1;
  119. self.tabBar.selectedItemIndex = 0;
  120. }
  121. // 更新scrollView的content size
  122. if (self.scrollView) {
  123. self.scrollView.contentSize = CGSizeMake(self.contentViewFrame.size.width * _viewControllers.count,
  124. self.contentViewFrame.size.height);
  125. }
  126. }
  127. - (void)setContentViewFrame:(CGRect)contentViewFrame {
  128. _contentViewFrame = contentViewFrame;
  129. [self updateContentViewsFrame];
  130. }
  131. - (void)setContentScrollEnabledAndTapSwitchAnimated:(BOOL)switchAnimated {
  132. if (!self.scrollView) {
  133. self.scrollView = [[JXHomeScrollView alloc] initWithFrame:self.contentViewFrame];
  134. self.scrollView.pagingEnabled = YES;
  135. self.scrollView.showsHorizontalScrollIndicator = NO;
  136. self.scrollView.showsVerticalScrollIndicator = NO;
  137. self.scrollView.scrollsToTop = NO;
  138. self.scrollView.delegate = self.tabBar;
  139. [self.view insertSubview:self.scrollView belowSubview:self.tabBar];
  140. self.scrollView.contentSize = CGSizeMake(self.contentViewFrame.size.width * _viewControllers.count,
  141. self.contentViewFrame.size.height);
  142. }
  143. [self updateContentViewsFrame];
  144. self.contentSwitchAnimated = switchAnimated;
  145. }
  146. - (void)updateContentViewsFrame {
  147. if (!_didViewAppeared) {
  148. return;
  149. }
  150. if (self.scrollView) {
  151. self.scrollView.frame = self.contentViewFrame;
  152. self.scrollView.contentSize = CGSizeMake(self.contentViewFrame.size.width * _viewControllers.count,
  153. self.contentViewFrame.size.height);
  154. [self.viewControllers enumerateObjectsUsingBlock:^(UIViewController * _Nonnull controller,
  155. NSUInteger idx, BOOL * _Nonnull stop) {
  156. if (controller.isViewLoaded) {
  157. controller.view.frame = CGRectMake(idx * self.contentViewFrame.size.width,
  158. 0,
  159. self.contentViewFrame.size.width,
  160. self.contentViewFrame.size.height);
  161. }
  162. }];
  163. [self.scrollView scrollRectToVisible:self.selectedController.view.frame animated:NO];
  164. } else {
  165. //self.selectedController.view.frame = CGRectMake(0,44, JX_SCREEN_HEIGHT-JX_SCREEN_TOP-70, 0);
  166. self.selectedController.view.frame = self.contentViewFrame;
  167. }
  168. }
  169. - (void)setSelectedControllerIndex:(NSInteger)selectedControllerIndex {
  170. UIViewController *oldController = nil;
  171. if (_selectedControllerIndex >= 0) {
  172. oldController = self.viewControllers[_selectedControllerIndex];
  173. }
  174. UIViewController *curController = self.viewControllers[selectedControllerIndex];
  175. BOOL isAppearFirstTime = YES;
  176. if (self.scrollView) {
  177. // contentView支持滚动
  178. // 调用oldController的viewWillDisappear方法
  179. [oldController viewWillDisappear:NO];
  180. if (!curController.view.superview) {
  181. // superview为空,表示为第一次加载,设置frame,并添加到scrollView
  182. curController.view.frame = CGRectMake(selectedControllerIndex * self.scrollView.frame.size.width,
  183. 0,
  184. self.scrollView.frame.size.width,
  185. self.scrollView.frame.size.height);
  186. [self.scrollView addSubview:curController.view];
  187. } else {
  188. // superview不为空,表示为已经加载过了,调用viewWillAppear方法
  189. isAppearFirstTime = NO;
  190. [curController viewWillAppear:NO];
  191. }
  192. // 切换到curController
  193. [self.scrollView scrollRectToVisible:curController.view.frame animated:self.contentSwitchAnimated];
  194. } else {
  195. // contentView不支持滚动
  196. // 将oldController的view移除
  197. if (oldController) {
  198. [oldController.view removeFromSuperview];
  199. }
  200. [self.view insertSubview:curController.view belowSubview:self.tabBar];
  201. // 设置curController.view的frame
  202. if (!CGRectEqualToRect(curController.view.frame, self.contentViewFrame)) {
  203. curController.view.frame = self.contentViewFrame;
  204. }
  205. }
  206. // 当contentView为scrollView及其子类时,设置它支持点击状态栏回到顶部
  207. if (oldController && [oldController.view isKindOfClass:[UIScrollView class]]) {
  208. [(UIScrollView *)oldController.view setScrollsToTop:NO];
  209. }
  210. if ([curController.view isKindOfClass:[UIScrollView class]]) {
  211. [(UIScrollView *)curController.view setScrollsToTop:YES];
  212. }
  213. _selectedControllerIndex = selectedControllerIndex;
  214. // 调用状态切换的回调方法
  215. [oldController tabItemDidDeselected];
  216. [curController tabItemDidSelected];
  217. if (self.scrollView) {
  218. [oldController viewDidDisappear:NO];
  219. if (!isAppearFirstTime) {
  220. [curController viewDidAppear:NO];
  221. }
  222. }
  223. }
  224. - (UIViewController *)selectedController {
  225. if (self.selectedControllerIndex >= 0) {
  226. return self.viewControllers[self.selectedControllerIndex];
  227. }
  228. return nil;
  229. }
  230. #pragma mark - YPTabBarDelegate
  231. - (void)yp_tabBar:(YPTabBar *)tabBar didSelectedItemAtIndex:(NSInteger)index {
  232. if (index == self.selectedControllerIndex) {
  233. return;
  234. }
  235. self.selectedControllerIndex = index;
  236. }
  237. @end
  238. @implementation UIViewController (YPTabBarController)
  239. - (NSString *)yp_tabItemTitle {
  240. return objc_getAssociatedObject(self, _cmd);
  241. }
  242. - (void)setYp_tabItemTitle:(NSString *)yp_tabItemTitle {
  243. objc_setAssociatedObject(self, @selector(yp_tabItemTitle), yp_tabItemTitle, OBJC_ASSOCIATION_COPY_NONATOMIC);
  244. }
  245. - (UIImage *)yp_tabItemImage {
  246. return objc_getAssociatedObject(self, _cmd);
  247. }
  248. - (void)setYp_tabItemImage:(UIImage *)yp_tabItemImage {
  249. objc_setAssociatedObject(self, @selector(yp_tabItemImage), yp_tabItemImage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  250. }
  251. - (UIImage *)yp_tabItemSelectedImage {
  252. return objc_getAssociatedObject(self, _cmd);
  253. }
  254. - (void)setYp_tabItemSelectedImage:(UIImage *)yp_tabItemSelectedImage {
  255. objc_setAssociatedObject(self, @selector(yp_tabItemSelectedImage), yp_tabItemSelectedImage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  256. }
  257. - (YPTabItem *)yp_tabItem {
  258. YPTabBar *tabBar = self.yp_tabBarController.tabBar;
  259. NSInteger index = [self.yp_tabBarController.viewControllers indexOfObject:self];
  260. return tabBar.items[index];
  261. }
  262. - (YPTabBarController *)yp_tabBarController {
  263. return (YPTabBarController *)self.parentViewController;
  264. }
  265. - (void)tabItemDidSelected {
  266. }
  267. - (void)tabItemDidDeselected {
  268. }
  269. @end