YMBaseViewController.m 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. //
  2. // YMBaseViewController.m
  3. // MSYOUPAI
  4. //
  5. // Created by YoMi on 2024/2/4.
  6. // Copyright © 2024 MS. All rights reserved.
  7. //
  8. #import "YMBaseViewController.h"
  9. #import "YYKit.h"
  10. @interface YMBaseViewController ()
  11. @property (nonatomic, strong, readwrite) YMBaseViewModel *viewModel;
  12. @end
  13. @implementation YMBaseViewController
  14. + (instancetype)allocWithZone:(struct _NSZone *)zone {
  15. YMBaseViewController *viewController = [super allocWithZone:zone];
  16. @weakify(viewController)
  17. [[viewController rac_signalForSelector:@selector(viewDidLoad)] subscribeNext:^(id x) {
  18. @strongify(viewController)
  19. [viewController ym_setupViews];
  20. [viewController ym_bindViewModel];
  21. }];
  22. return viewController;
  23. }
  24. - (instancetype)initWithViewModel:(YMBaseViewModel*)viewModel{
  25. if (self = [super init]) {
  26. self.viewModel = viewModel;
  27. }
  28. return self;
  29. }
  30. - (void)viewDidLoad {
  31. [super viewDidLoad];
  32. self.extendedLayoutIncludesOpaqueBars = NO;
  33. self.navigationController.navigationBar.hidden = YES;
  34. self.view.backgroundColor = UIColor.whiteColor;
  35. if(@available(iOS 15.0,*)){
  36. [UITableView appearance].sectionHeaderTopPadding = 0;
  37. }
  38. RAC(self.ym_customNavView.ym_customNavItem, title) = RACObserve(self.viewModel, customNavTitle);
  39. [self.view addSubview:self.ym_customNavView];
  40. [self.ym_customNavView mas_makeConstraints:^(MASConstraintMaker *make) {
  41. make.top.equalTo(self.view);
  42. make.left.equalTo(self.view);
  43. make.right.equalTo(self.view);
  44. make.height.mas_equalTo(kYMNavHeight);
  45. }];
  46. /* 非根视图,添加返回按钮 */
  47. if (self.navigationController.viewControllers.count > 1
  48. && !self.isHideLeftItem) {
  49. @weakify(self)
  50. [self setLeftBarButtonWithImage:@"ym_navigation_black_icon" block:^(id _Nonnull sender) {
  51. @strongify(self)
  52. [self.navigationController popViewControllerAnimated:YES];
  53. }];
  54. }
  55. }
  56. - (void)viewWillAppear:(BOOL)animated {
  57. [super viewWillAppear:animated];
  58. self.navigationController.navigationBar.hidden = YES;
  59. }
  60. - (void)setYm_navigationStyle:(YMBaseNavigationStyle)ym_navigationStyle{
  61. _ym_navigationStyle = ym_navigationStyle;
  62. switch (ym_navigationStyle) {
  63. case YMBaseNavigationStyleClearBgWhiteBackArrow:
  64. {
  65. NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
  66. paragraphStyle.alignment = NSTextAlignmentCenter;
  67. paragraphStyle.lineSpacing = 1;
  68. NSDictionary *attributes= @{
  69. NSForegroundColorAttributeName:UIColor.whiteColor,
  70. NSParagraphStyleAttributeName:paragraphStyle
  71. };
  72. if (@available(iOS 15.0, *)) {
  73. UINavigationBarAppearance *barApp = [UINavigationBarAppearance new];
  74. barApp.backgroundColor = UIColor.clearColor;
  75. barApp.backgroundEffect = nil;
  76. barApp.titleTextAttributes = attributes;
  77. barApp.shadowColor = nil;
  78. [self.ym_customNavView.ym_customNavBar setScrollEdgeAppearance:barApp];
  79. [self.ym_customNavView.ym_customNavBar setStandardAppearance:barApp];
  80. }else{
  81. [self.ym_customNavView.ym_customNavBar setShadowImage:[UIImage new]];
  82. [self.ym_customNavView.ym_customNavBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
  83. [self.ym_customNavView.ym_customNavBar setTitleTextAttributes:attributes];
  84. }
  85. self.ym_customNavView.backgroundColor = UIColor.clearColor;
  86. self.ym_customNavView.ym_customNavBar.backgroundColor = UIColor.clearColor;
  87. self.ym_customNavView.ym_customNavBar.translucent = YES;
  88. if (self.navigationController.viewControllers.count > 1
  89. && !self.isHideLeftItem) {
  90. @weakify(self)
  91. [self setLeftBarButtonWithImage:@"ym_navigation_white_icon" block:^(id _Nonnull sender) {
  92. @strongify(self)
  93. [self.navigationController popViewControllerAnimated:YES];
  94. }];
  95. }
  96. self.ym_customNavView.ym_customNavBarLine.hidden = YES;
  97. }
  98. break;
  99. case YMBaseNavigationStyleClearBgBlackBackArrow:
  100. {
  101. NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
  102. paragraphStyle.alignment = NSTextAlignmentCenter;
  103. paragraphStyle.lineSpacing = 1;
  104. NSDictionary *attributes= @{
  105. NSForegroundColorAttributeName:UIColor.blackColor,
  106. NSParagraphStyleAttributeName:paragraphStyle
  107. };
  108. if (@available(iOS 15.0, *)) {
  109. UINavigationBarAppearance *barApp = [UINavigationBarAppearance new];
  110. barApp.backgroundColor = UIColor.clearColor;
  111. barApp.backgroundEffect = nil;
  112. barApp.titleTextAttributes = attributes;
  113. barApp.shadowColor = nil;
  114. [self.ym_customNavView.ym_customNavBar setScrollEdgeAppearance:barApp];
  115. [self.ym_customNavView.ym_customNavBar setStandardAppearance:barApp];
  116. }else{
  117. [self.ym_customNavView.ym_customNavBar setShadowImage:[UIImage new]];
  118. [self.ym_customNavView.ym_customNavBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
  119. [self.ym_customNavView.ym_customNavBar setTitleTextAttributes:attributes];
  120. }
  121. self.ym_customNavView.backgroundColor = UIColor.clearColor;
  122. self.ym_customNavView.ym_customNavBar.backgroundColor = UIColor.clearColor;
  123. self.ym_customNavView.ym_customNavBar.translucent = YES;
  124. if (self.navigationController.viewControllers.count > 1
  125. && !self.isHideLeftItem) {
  126. @weakify(self)
  127. [self setLeftBarButtonWithImage:@"ym_navigation_black_icon" block:^(id _Nonnull sender) {
  128. @strongify(self)
  129. [self.navigationController popViewControllerAnimated:YES];
  130. }];
  131. }
  132. self.ym_customNavView.ym_customNavBarLine.hidden = YES;
  133. }
  134. break;
  135. default:
  136. {
  137. self.ym_customNavView.ym_customNavBar.barTintColor = UIColor.whiteColor;
  138. self.ym_customNavView.backgroundColor = UIColor.whiteColor;
  139. NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
  140. paragraphStyle.alignment = NSTextAlignmentCenter;
  141. paragraphStyle.lineSpacing = 1;
  142. NSDictionary *attributes= @{
  143. NSForegroundColorAttributeName:UIColor.blackColor,
  144. NSParagraphStyleAttributeName:paragraphStyle
  145. };
  146. [self.ym_customNavView.ym_customNavBar setTitleTextAttributes:attributes];
  147. if (self.navigationController.viewControllers.count > 1
  148. && !self.isHideLeftItem) {
  149. @weakify(self)
  150. [self setLeftBarButtonWithImage:@"ym_navigation_black_icon" block:^(id _Nonnull sender) {
  151. @strongify(self)
  152. [self.navigationController popViewControllerAnimated:YES];
  153. }];
  154. }
  155. self.ym_customNavView.ym_customNavBarLine.hidden = YES;
  156. }
  157. break;
  158. }
  159. }
  160. - (void)setNavHidden:(BOOL)hidden {
  161. [self.ym_customNavView setHidden:hidden];
  162. }
  163. - (void)setTitle:(NSString *)title {
  164. self.ym_customNavView.ym_customNavItem.title = title;
  165. }
  166. - (NSString *)title {
  167. return self.ym_customNavView.ym_customNavItem.title;
  168. }
  169. /** 添加控件 最好最后加上[self.view setNeedsUpdateConstraints]和[self.view updateConstraintsIfNeeded],以防不调用updateViewConstraints*/
  170. - (void)ym_setupViews {
  171. }
  172. /** 绑定VM*/
  173. - (void)ym_bindViewModel {
  174. }
  175. - (void)headerRefreshing{
  176. }
  177. - (void)footerRefreshing{
  178. }
  179. - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  180. [self.view endEditing:YES];
  181. }
  182. - (YMBaseCustomNavView *)ym_customNavView {
  183. if (!_ym_customNavView) {
  184. _ym_customNavView = [[YMBaseCustomNavView alloc] init];
  185. _ym_customNavView.backgroundColor = UIColor.whiteColor;
  186. }
  187. return _ym_customNavView;
  188. }
  189. - (MJRefreshNormalHeader *)refreshHeader{
  190. if(!_refreshHeader){
  191. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的headerRefreshing方法)
  192. _refreshHeader = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(headerRefreshing)];
  193. }
  194. return _refreshHeader;
  195. }
  196. - (MJRefreshAutoNormalFooter *)loadMoreFooter{
  197. if(!_loadMoreFooter){
  198. // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的footerRefreshing方法)
  199. _loadMoreFooter = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(footerRefreshing)];
  200. _loadMoreFooter.triggerAutomaticallyRefreshPercent = 0.1;
  201. }
  202. return _loadMoreFooter;
  203. }
  204. - (MJRefreshAutoNormalFooter *)noLoadMoreFooter{
  205. if(!_noLoadMoreFooter){
  206. _noLoadMoreFooter = [[MJRefreshAutoNormalFooter alloc]initWithFrame:CGRectZero];
  207. _noLoadMoreFooter.backgroundColor = [UIColor clearColor];
  208. _noLoadMoreFooter.state = MJRefreshStateIdle;
  209. _noLoadMoreFooter.mj_h = 0;//重新设置高度,不让看到它,并且当设置为table.footer时,table会自动调整自己的高度
  210. _noLoadMoreFooter.clipsToBounds = YES;//不让看不到菊花
  211. }
  212. return _noLoadMoreFooter;
  213. }
  214. @end
  215. @implementation YMBaseViewController (YMNavBar)
  216. /** 左Bar按钮+标题*/
  217. - (void)setLeftBarButtonWithTitle:(NSString *)title
  218. block:(void (^)(id sender))block {
  219. self.ym_customNavView.ym_customNavItem.leftBarButtonItem = [self barButtonWithPosition:YES title:title block:block];
  220. }
  221. /** 右Bar按钮+标题*/
  222. - (void)setRightBarButtonWithTitle:(NSString *)title
  223. block:(void (^)(id sender))block {
  224. self.ym_customNavView.ym_customNavItem.rightBarButtonItem = [self barButtonWithPosition:NO title:title block:block];
  225. }
  226. /** 左Bar按钮+图片*/
  227. - (void)setLeftBarButtonWithImage:(NSString *)image
  228. block:(void (^)(id sender))block {
  229. [self setLeftBarButtonWithNormalImage:image highlightedImage:nil block:block];
  230. }
  231. /** 右Bar按钮+图片*/
  232. - (void)setRightBarButtonWithImage:(NSString *)image block:(void (^)(id sender))block {
  233. [self setRightBarButtonWithNormalImage:image highlightedImage:nil block:block];
  234. }
  235. /** 左Bar按钮+选中图片+未选中图片*/
  236. - (void)setLeftBarButtonWithNormalImage:(NSString *)normal
  237. highlightedImage:(NSString *)highlighted
  238. block:(void (^)(id sender))block {
  239. self.ym_customNavView.ym_customNavItem.leftBarButtonItem = [self barButtonWithPosition:YES normalImage:normal highlightedImage:highlighted block:block];
  240. }
  241. /** 右Bar按钮+选中图片+未选中图片*/
  242. - (void)setRightBarButtonWithNormalImage:(NSString *)normal
  243. highlightedImage:(NSString *)highlighted
  244. block:(void (^)(id sender))block {
  245. self.ym_customNavView.ym_customNavItem.rightBarButtonItem = [self barButtonWithPosition:NO normalImage:normal highlightedImage:highlighted block:block];
  246. }
  247. /** 左Bar多个按钮*/
  248. - (void)setLeftBarButtonWithButtons:(NSArray *)buttons {
  249. self.ym_customNavView.ym_customNavItem.leftBarButtonItems = [self barItemsWithPosition:YES buttons:buttons];
  250. }
  251. /** 右Bar多个按钮*/
  252. - (void)setRightBarButtonWithButtons:(NSArray *)buttons {
  253. self.ym_customNavView.ym_customNavItem.rightBarButtonItems = [self barItemsWithPosition:NO buttons:buttons];
  254. }
  255. /** 左Bar自定义View*/
  256. - (void)setLeftBarButtonWithCustomView:(UIView *)customView {
  257. self.ym_customNavView.ym_customNavItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:customView];
  258. }
  259. /** 右Bar自定义View*/
  260. - (void)setRightBarButtonWithCustomView:(UIView *)customView {
  261. self.ym_customNavView.ym_customNavItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:customView];
  262. }
  263. #pragma mark - private method
  264. - (UIBarButtonItem *)barButtonWithPosition:(BOOL)onLeft
  265. title:(NSString *)title
  266. block:(void (^)(id sender))block {
  267. UIButton *navBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  268. [navBtn setBounds:CGRectMake(0, 0, 70, 44)];
  269. [navBtn setTitle:title forState:UIControlStateNormal];
  270. [navBtn setTitleColor:HexColorFromRGB(0x616161) forState:UIControlStateNormal];
  271. [navBtn setTitleColor:HexColorFromRGB(0x616161) forState:UIControlStateHighlighted];
  272. navBtn.titleLabel.font = [UIFont systemFontOfSize:16];
  273. navBtn.backgroundColor = [UIColor clearColor];
  274. if (onLeft) {
  275. navBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
  276. } else {
  277. navBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
  278. }
  279. if (block) {
  280. [navBtn setBlockForControlEvents:UIControlEventTouchUpInside block:block];
  281. }
  282. return [[UIBarButtonItem alloc] initWithCustomView:navBtn];
  283. }
  284. - (UIBarButtonItem *)barButtonWithPosition:(BOOL)onLeft
  285. image:(UIImage *)image
  286. block:(void (^)(id sender))block {
  287. UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  288. [button setBounds:CGRectMake(0, 0, 44, 44)];
  289. [button setImage:image forState:UIControlStateNormal];
  290. button.backgroundColor = [UIColor clearColor];
  291. if (onLeft) {
  292. button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
  293. } else {
  294. button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
  295. }
  296. if (block) {
  297. [button setBlockForControlEvents:UIControlEventTouchUpInside block:block];
  298. }
  299. return [[UIBarButtonItem alloc] initWithCustomView:button];
  300. }
  301. - (UIBarButtonItem *)barButtonWithPosition:(BOOL)onLeft
  302. normalImage:(NSString *)normal
  303. highlightedImage:(NSString *)highlighted
  304. block:(void (^)(id sender))block {
  305. UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  306. [button setBounds:CGRectMake(0, 0, 44, 44)];
  307. [button setImage:[UIImage imageNamed:normal] forState:UIControlStateNormal];
  308. [button setImage:[UIImage imageNamed:highlighted ?: normal] forState:UIControlStateHighlighted];
  309. button.backgroundColor = [UIColor clearColor];
  310. if (onLeft) {
  311. button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
  312. } else {
  313. button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
  314. }
  315. if (block) {
  316. [button setBlockForControlEvents:UIControlEventTouchUpInside block:block];
  317. }
  318. return [[UIBarButtonItem alloc] initWithCustomView:button];
  319. }
  320. - (NSArray *)barItemsWithPosition:(BOOL)onLeft
  321. buttons:(NSArray *)buttons {
  322. NSMutableArray *barItems = [NSMutableArray array];
  323. for (UIView *tmpView in buttons) {
  324. UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:tmpView];
  325. UIBarButtonItem *negativeSeperator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
  326. negativeSeperator.width = 14;
  327. [barItems addObject:negativeSeperator];
  328. [barItems addObject:item];
  329. }
  330. return [barItems copy];
  331. }
  332. @end