RQBaseNavigationController.m 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. //
  2. // RQBaseNavigationController.m
  3. // RQCommon
  4. //
  5. // Created by 张嵘 on 2018/11/13.
  6. // Copyright © 2018 张嵘. All rights reserved.
  7. //
  8. #import "RQBaseNavigationController.h"
  9. //#import "RQBaseViewController.h"
  10. @interface RQBaseNavigationController ()
  11. @property (nonatomic , weak , readwrite) UIImageView * navigationBottomLine;// 导航栏分隔线
  12. @end
  13. @implementation RQBaseNavigationController
  14. // 第一次使用这个类调用一次
  15. + (void)initialize {
  16. // 2.设置UINavigationBar的主题
  17. [self _setupNavigationBarTheme];
  18. // 3.设置UIBarButtonItem的主题
  19. [self _setupBarButtonItemTheme];
  20. }
  21. - (void)viewDidLoad {
  22. [super viewDidLoad];
  23. // 初始化
  24. [self _setup];
  25. }
  26. #pragma mark - 初始化
  27. - (void) _setup {
  28. [self _setupNavigationBarBottomLine];
  29. if (@available(iOS 15.0, *)) {
  30. UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];
  31. [appearance configureWithOpaqueBackground];
  32. /// 设置导航栏背景色
  33. appearance.backgroundColor = RQ_MAIN_BACKGROUNDCOLOR;
  34. /// 设置文字属性
  35. NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
  36. textAttrs[NSFontAttributeName] = RQMediumFont(18.0f);
  37. textAttrs[NSForegroundColorAttributeName] = RQ_MAIN_TEXT_COLOR_1;
  38. appearance.titleTextAttributes = textAttrs;
  39. /// 设置导航栏下边界分割线透明
  40. appearance.shadowImage = [UIImage imageWithColor:UIColor.clearColor];
  41. self.navigationBar.standardAppearance = appearance;
  42. self.navigationBar.scrollEdgeAppearance = self.navigationBar.standardAppearance;
  43. } else {
  44. // Fallback on earlier versions
  45. }
  46. }
  47. // 查询最后一条数据
  48. - (UIImageView *)_findHairlineImageViewUnder:(UIView *)view {
  49. if ([view isKindOfClass:UIImageView.class] && view.bounds.size.height <= 1.0) {
  50. return (UIImageView *)view;
  51. }
  52. for (UIView *subview in view.subviews){
  53. UIImageView *imageView = [self _findHairlineImageViewUnder:subview];
  54. if (imageView){
  55. return imageView;
  56. }
  57. }
  58. return nil;
  59. }
  60. #pragma mark - 设置导航栏的分割线
  61. - (void)_setupNavigationBarBottomLine {
  62. //!!!:这里之前设置系统的 navigationBarBottomLine.image = xxx;无效 Why? 隐藏了系统的 自己添加了一个分割线
  63. // 隐藏系统的导航栏分割线
  64. UIImageView *navigationBarBottomLine = [self _findHairlineImageViewUnder:self.navigationBar];
  65. navigationBarBottomLine.hidden = YES;
  66. // 添加自己的分割线
  67. CGFloat navSystemLineH = .5f;
  68. UIImageView *navSystemLine = [[UIImageView alloc] initWithFrame:CGRectMake(0, self.navigationBar.rq_height - navSystemLineH, RQ_SCREEN_WIDTH, navSystemLineH)];
  69. navSystemLine.backgroundColor = RQ_MAIN_LINE_COLOR_1;
  70. [self.navigationBar addSubview:navSystemLine];
  71. self.navigationBottomLine = navSystemLine;
  72. }
  73. /**
  74. * 设置UINavigationBarTheme的主题
  75. */
  76. + (void)_setupNavigationBarTheme {
  77. UINavigationBar *appearance = [UINavigationBar appearance];
  78. /// 设置背景
  79. //!!!: 必须设置为透明 不然布局有问题 ios8以下 会崩溃/ 如果iOS8以下 请再_setup里面 设置透明 self.navigationBar.translucent = YES;
  80. [appearance setTranslucent:YES]; /// 必须设置YES
  81. // 设置导航栏的样式
  82. [appearance setBarStyle:UIBarStyleDefault];
  83. //设置导航栏文字按钮的渲染色
  84. [appearance setTintColor:RQ_MAIN_TEXT_COLOR_1];
  85. // 设置导航栏的背景渲染色
  86. [appearance setBarTintColor:RQ_MAIN_BACKGROUNDCOLOR];
  87. // 设置文字属性
  88. NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
  89. textAttrs[NSFontAttributeName] = RQMediumFont(18.0f);
  90. textAttrs[NSForegroundColorAttributeName] = RQ_MAIN_TEXT_COLOR_1;
  91. // UIOffsetZero是结构体, 只要包装成NSValue对象, 才能放进字典\数组中
  92. NSShadow *shadow = [[NSShadow alloc] init];
  93. shadow.shadowOffset = CGSizeZero;
  94. textAttrs[NSShadowAttributeName] = shadow;
  95. [appearance setTitleTextAttributes:textAttrs];
  96. /// 去掉导航栏的阴影图片
  97. [appearance setShadowImage:[UIImage new]];
  98. }
  99. /**
  100. * 设置UIBarButtonItem的主题
  101. */
  102. + (void)_setupBarButtonItemTheme{
  103. // 通过appearance对象能修改整个项目中所有UIBarButtonItem的样式
  104. UIBarButtonItem *appearance = [UIBarButtonItem appearance];
  105. CGFloat fontSize = 16.0f;
  106. /**设置文字属性**/
  107. // 设置普通状态的文字属性
  108. NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
  109. textAttrs[NSForegroundColorAttributeName] = RQ_MAIN_TEXT_COLOR_1;
  110. textAttrs[NSFontAttributeName] = RQRegularFont(fontSize);
  111. NSShadow *shadow = [[NSShadow alloc] init];
  112. shadow.shadowOffset = CGSizeZero;
  113. textAttrs[NSShadowAttributeName] = shadow;
  114. [appearance setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
  115. // 设置高亮状态的文字属性
  116. NSMutableDictionary *highTextAttrs = [NSMutableDictionary dictionaryWithDictionary:textAttrs];
  117. highTextAttrs[NSForegroundColorAttributeName] = [[UIColor whiteColor] colorWithAlphaComponent:.5f];
  118. [appearance setTitleTextAttributes:highTextAttrs forState:UIControlStateHighlighted];
  119. // 设置不可用状态(disable)的文字属性
  120. NSMutableDictionary *disableTextAttrs = [NSMutableDictionary dictionaryWithDictionary:textAttrs];
  121. disableTextAttrs[NSForegroundColorAttributeName] = [[UIColor whiteColor] colorWithAlphaComponent:.5f];
  122. [appearance setTitleTextAttributes:disableTextAttrs forState:UIControlStateDisabled];
  123. }
  124. #pragma mark - Publi Method
  125. /// 显示导航栏的细线
  126. - (void)rq_showNavigationBottomLine {
  127. self.navigationBottomLine.hidden = NO;
  128. }
  129. /// 隐藏导航栏的细线
  130. - (void)rq_hideNavigationBottomLine {
  131. self.navigationBottomLine.hidden = YES;
  132. }
  133. /// 能拦截所有push进来的子控制器
  134. - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
  135. // 如果现在push的不是栈底控制器(最先push进来的那个控制器)
  136. if (self.viewControllers.count > 0){
  137. /// 隐藏底部tabbar
  138. viewController.hidesBottomBarWhenPushed = YES;
  139. NSString *title = @"";
  140. /// eg: [A push B]
  141. /// 1.取出当前的控制器的title , 也就是取出 A.title
  142. /// RQ Fixed: [[self topViewController] navigationItem].title 这样来获取title 而不是[[self topViewController] title]
  143. title = [[self topViewController] navigationItem].title? : @"";
  144. /// 2.判断要被Push的控制器(B)是否是 RQViewController ,
  145. if ([viewController isKindOfClass:[RQBaseViewController class]]) {
  146. RQBaseViewModel *viewModel = [(RQBaseViewController *)viewController viewModel];
  147. /// 3. 查看backTitle 是否有值
  148. title = viewModel.backTitle?:title;
  149. }
  150. // 4.这里可以设置导航栏的左右按钮 统一管理方法
  151. viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem rq_backItemWithTitle:@"" imageName:@"back_black" target:self action:@selector(rq_back)];
  152. UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
  153. if (RQ_iOS11_VERSTION_LATER) {
  154. negativeSpacer.width = 0;
  155. } else {
  156. negativeSpacer.width = -5;
  157. }
  158. viewController.navigationItem.leftBarButtonItems = @[negativeSpacer,viewController.navigationItem.leftBarButtonItem];
  159. }
  160. if ([self.viewControllers.lastObject isKindOfClass:[viewController class]]) {
  161. return;
  162. }
  163. // push
  164. [super pushViewController:viewController animated:animated];
  165. }
  166. /// 事件处理
  167. - (void)rq_back {
  168. [self popViewControllerAnimated:YES];
  169. }
  170. #pragma mark - Override
  171. - (BOOL)shouldAutorotate {
  172. return self.topViewController.shouldAutorotate;
  173. }
  174. - (UIInterfaceOrientationMask)supportedInterfaceOrientations{
  175. return self.topViewController.supportedInterfaceOrientations;
  176. }
  177. - (UIStatusBarStyle)preferredStatusBarStyle{
  178. return self.topViewController.preferredStatusBarStyle;
  179. }
  180. - (BOOL)prefersStatusBarHidden{
  181. return self.topViewController.prefersStatusBarHidden;
  182. }
  183. @end