酷店

UINavigationBar+handle.m 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. //
  2. // UINavigationBar+handle.m
  3. // blueCat
  4. //
  5. // Created by admin on 2019/6/17.
  6. // Copyright © 2019 best. All rights reserved.
  7. //
  8. #import "UINavigationBar+handle.h"
  9. #import <objc/runtime.h>
  10. @class MyNavView;
  11. @interface UINavigationBar()
  12. @property (nonatomic, strong) UIImage *backClearImage;
  13. @property (nonatomic, strong) UIImage *lineClearImage;
  14. @property (nonatomic, strong) MyNavView *myNavView; //自定义插入层,自定义操作都要在这一层上进行
  15. @property (nonatomic, assign) BOOL hiddenBottom;
  16. @end
  17. static char backClear_key, lineClear_key, myNavView_key, hiddenBottom_key;
  18. @implementation UINavigationBar (handle)
  19. #pragma mark -- runtime:get/set
  20. - (void)setBackClearImage:(UIImage *)backClearImage {
  21. objc_setAssociatedObject(self, &backClear_key, backClearImage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  22. }
  23. - (UIImage *)backClearImage {
  24. return objc_getAssociatedObject(self, &backClear_key);
  25. }
  26. - (void)setLineClearImage:(UIImage *)lineClearImage {
  27. objc_setAssociatedObject(self, &lineClear_key, lineClearImage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  28. }
  29. - (UIImage *)lineClearImage {
  30. return objc_getAssociatedObject(self, &lineClear_key);
  31. }
  32. - (void)setMyNavView:(MyNavView *)myNavView {
  33. objc_setAssociatedObject(self, &myNavView_key, myNavView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  34. }
  35. - (MyNavView *)myNavView {
  36. return objc_getAssociatedObject(self, &myNavView_key);
  37. }
  38. - (void)setHiddenBottom:(BOOL)hiddenBottom {
  39. objc_setAssociatedObject(self, &hiddenBottom_key, @(hiddenBottom), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  40. }
  41. - (BOOL)hiddenBottom {
  42. return [objc_getAssociatedObject(self, &hiddenBottom_key) boolValue];
  43. }
  44. #pragma mark -- function
  45. - (void)navBarAlpha:(CGFloat)alpha isOpaque:(BOOL)opaque {
  46. [self clearSystemLayerIsOpaque:opaque];
  47. if (!self.myNavView) {
  48. //状态栏高度
  49. CGFloat statusHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
  50. //导航栏高度
  51. CGFloat barHeight = self.bounds.size.height;
  52. CGRect barBounds = self.bounds;
  53. barBounds.size.height = statusHeight + barHeight;
  54. self.myNavView = [[MyNavView alloc]initWithFrame:barBounds];
  55. [self navBarBottomLineHidden:self.hiddenBottom];
  56. }
  57. self.myNavView.alpha = alpha;
  58. //通过kvc找到系统导航栏背景层,把自定义层添加到背景层
  59. /* 系统背景层无法改变其属性 所以通过添加自定义层,改变自定义层去实现效果*/
  60. [[self valueForKey:@"backgroundView"] addSubview:self.myNavView];
  61. }
  62. - (void)navBarBackGroundColor:(UIColor *)color image:(UIImage *)barImage isOpaque:(BOOL)opaque {
  63. [self clearSystemLayerIsOpaque:opaque];
  64. if (!self.myNavView) {
  65. //状态栏高度
  66. CGFloat statusHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
  67. //导航栏高度
  68. CGFloat barHeight = self.bounds.size.height;
  69. CGRect barBounds = self.bounds;
  70. barBounds.size.height = statusHeight + barHeight;
  71. self.myNavView = [[MyNavView alloc]initWithFrame:barBounds];
  72. [self navBarBottomLineHidden:self.hiddenBottom];
  73. }
  74. if (color) {
  75. self.myNavView.F4Color = color;
  76. }
  77. if (barImage) {
  78. self.myNavView.backImage = barImage;
  79. }
  80. //通过kvc找到系统导航栏背景层,把自定义层添加到背景层
  81. /*系统背景层无法改变其属性 所以通过添加自定义层,改变自定义层上的属性去实现效果*/
  82. [[self valueForKey:@"backgroundView"] addSubview:self.myNavView];
  83. }
  84. - (void)navBarMyLayerHeight:(CGFloat)height isOpaque:(BOOL)opaque {
  85. height = height < 0 ? 0 : height;
  86. [self clearSystemLayerIsOpaque:opaque];
  87. if (!self.myNavView) {
  88. self.myNavView = [[MyNavView alloc]init];
  89. [self navBarBottomLineHidden:self.hiddenBottom];
  90. }
  91. [self.myNavView setFrame:CGRectMake(0, 0, self.bounds.size.width, height)];
  92. //通过kvc找到系统导航栏背景层,把自定义层添加到背景层
  93. /* 亲测,系统背景层无法改变其属性 所以通过添加自定义层,改变自定义层上的属性去实现效果*/
  94. [[self valueForKey:@"backgroundView"] addSubview:self.myNavView];
  95. }
  96. - (void)navBarBottomLineHidden:(BOOL)hidden {
  97. self.hiddenBottom = hidden;
  98. //如果是自定义图层
  99. if (self.myNavView && self.myNavView.hiddenBottomLine != hidden) {
  100. self.myNavView.hiddenBottomLine = hidden;
  101. } else {
  102. //如果是系统层
  103. if (hidden) {
  104. if (!self.lineClearImage) {
  105. self.lineClearImage = [[UIImage alloc]init];
  106. [self setShadowImage:self.lineClearImage];
  107. }
  108. } else {
  109. if (self.lineClearImage) {
  110. self.lineClearImage = nil;
  111. [self setShadowImage:self.lineClearImage];
  112. }
  113. }
  114. }
  115. }
  116. //还原到系统初始状态
  117. - (void)navBarToBeSystem {
  118. if (self.myNavView) {
  119. [self.myNavView removeFromSuperview];
  120. self.myNavView = nil;
  121. }
  122. if (self.lineClearImage) {
  123. self.lineClearImage = nil;
  124. }
  125. if (self.backClearImage) {
  126. self.backClearImage = nil;
  127. }
  128. [self setBackgroundImage:nil
  129. forBarMetrics:UIBarMetricsDefault];
  130. [self setShadowImage:nil];
  131. self.barStyle = UIBarStyleDefault;
  132. }
  133. //去掉系统导航栏特征
  134. - (void)clearSystemLayerIsOpaque:(BOOL)opaque{
  135. //通过插入空image把背景变透明
  136. if (!self.backClearImage) {
  137. self.backClearImage = [[UIImage alloc]init];
  138. [self setBackgroundImage:self.backClearImage
  139. forBarMetrics:UIBarMetricsDefault];
  140. }
  141. self.barStyle = opaque ? UIBarStyleBlackOpaque : UIBarStyleDefault;
  142. //去掉系统底线,使用自定义底线
  143. if (!self.lineClearImage) {
  144. self.lineClearImage = [[UIImage alloc]init];
  145. [self setShadowImage:self.lineClearImage];
  146. }
  147. }
  148. @end
  149. #pragma mark -- 自定义导航栏层
  150. @interface MyNavView()
  151. @property (nonatomic, strong) UIImageView * _Nullable backImageView;
  152. @property (nonatomic, strong) UIView * _Nullable bottomLine;
  153. @end
  154. @implementation MyNavView
  155. - (instancetype)initWithFrame:(CGRect)frame {
  156. self = [super initWithFrame:frame];
  157. if (self) {
  158. }
  159. return self;
  160. }
  161. - (void)setFrame:(CGRect)frame {
  162. [super setFrame:frame];
  163. [self creatMainUIByFrame:frame];
  164. }
  165. - (void)creatMainUIByFrame:(CGRect)frame {
  166. CGFloat height = frame.size.height;
  167. CGFloat width = frame.size.width;
  168. [self.backImageView setFrame:CGRectMake(0, 0, width, height)];
  169. [self addSubview:self.backImageView];
  170. [self.bottomLine setFrame:CGRectMake(0, height-0.5, width, 0.5)];
  171. [self addSubview:self.bottomLine];
  172. }
  173. //底层背景层永远透明
  174. - (void)setBackgroundColor:(UIColor *)backgroundColor {
  175. [super setBackgroundColor:[UIColor clearColor]];
  176. }
  177. //设置图片背景颜色
  178. - (void)setF4Color:(UIColor *)F4Color {
  179. _F4Color = F4Color;
  180. self.backImageView.backgroundColor = F4Color;
  181. }
  182. //设置图片背景透明度
  183. - (void)setAlpha:(CGFloat)alpha {
  184. _alpha = alpha;
  185. self.backImageView.alpha = alpha;
  186. }
  187. //设置图片
  188. - (void)setBackImage:(UIImage *)backImage {
  189. _backImage = backImage;
  190. self.backImageView.image = backImage;
  191. }
  192. - (void)setHiddenBottomLine:(BOOL)hiddenBottomLine {
  193. _hiddenBottomLine = hiddenBottomLine;
  194. self.bottomLine.hidden = hiddenBottomLine;
  195. }
  196. #pragma mark -- 懒加载视图
  197. - (UIImageView *)backImageView {
  198. if (!_backImageView) {
  199. _backImageView = [UIImageView new];
  200. _backImageView.clipsToBounds = YES;
  201. _backImageView.contentMode = UIViewContentModeTop;
  202. }
  203. return _backImageView;
  204. }
  205. - (UIView *)bottomLine {
  206. if (!_bottomLine) {
  207. _bottomLine = [UIView new];
  208. [_bottomLine setBackgroundColor:[UIColor grayColor]];
  209. }
  210. return _bottomLine;
  211. }
  212. @end