InstrumentChooseViewController.m 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. //
  2. // InstrumentChooseViewController.m
  3. // KulexiuForTeacher
  4. //
  5. // Created by 王智 on 2022/4/11.
  6. //
  7. #import "InstrumentChooseViewController.h"
  8. #import "InstrumentMessageModel.h"
  9. #import "InstrumentChooseCell.h"
  10. #import "InstrumentChooseBottonView.h"
  11. #import "InstrumentHeaderView.h"
  12. #define INSTRUMENT_ROWCOUNT (IS_IPAD ? 5 : 3)
  13. @interface InstrumentChooseViewController ()<UICollectionViewDelegate,UICollectionViewDataSource>
  14. @property (nonatomic, copy) ChooseInstrumentCallback callback;
  15. @property (nonatomic, copy) UICollectionView *collectionView;
  16. @property (nonatomic, strong) NSMutableArray *parentArray;
  17. @property (nonatomic, strong) NSMutableArray *instrumentArray;
  18. @property (nonatomic, copy) InstrumentChooseBottonView *bottomView;
  19. @property (nonatomic, strong) NSMutableArray *chooseArray;
  20. @property (nonatomic, strong) InstrumentMessageModel *chooseModel;
  21. @property (nonatomic, strong) NSIndexPath *chooseIndexPath;
  22. @end
  23. @implementation InstrumentChooseViewController
  24. - (void)chooseCallback:(ChooseInstrumentCallback)callback {
  25. if (callback) {
  26. self.callback = callback;
  27. }
  28. }
  29. - (void)viewDidLoad {
  30. [super viewDidLoad];
  31. // Do any additional setup after loading the view.
  32. NSString *headTitle = self.isSingleChoose ? @"乐器选择" : @"可教授乐器";
  33. [self allocTitle:headTitle];
  34. [self configUI];
  35. [self requestInstrumentMessage];
  36. }
  37. - (void)configUI {
  38. [self.scrollView removeFromSuperview];
  39. [self.view addSubview:self.bottomView];
  40. [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
  41. make.left.right.mas_equalTo(self.view);
  42. make.bottom.mas_equalTo(self.view.mas_bottom).offset(-iPhoneXSafeBottomMargin);
  43. make.height.mas_equalTo(90);
  44. }];
  45. UIView *headView = [[UIView alloc] init];
  46. headView.layer.backgroundColor = [UIColor whiteColor].CGColor;
  47. [self.view addSubview:headView];
  48. [headView mas_makeConstraints:^(MASConstraintMaker *make) {
  49. make.top.mas_equalTo(self.view.mas_top).mas_offset(10);
  50. make.left.mas_equalTo(self.view.mas_left).offset(14.0f);
  51. make.right.mas_equalTo(self.view.mas_right).offset(-14.0f);
  52. make.height.mas_equalTo(36.0f);
  53. }];
  54. headView.layer.cornerRadius = 10.0f;
  55. headView.layer.masksToBounds = YES;
  56. UILabel *tipsLabel = [[UILabel alloc] init];
  57. tipsLabel.text = self.isSingleChoose ? @"最多可选择1个乐器" : @"最多可选择5个乐器";
  58. tipsLabel.textColor = HexRGB(0xFF9E5A);
  59. tipsLabel.font = [UIFont systemFontOfSize:14.0f];
  60. [headView addSubview:tipsLabel];
  61. [tipsLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  62. make.left.mas_equalTo(headView.mas_left).offset(11.0f);
  63. make.right.mas_equalTo(headView.mas_right).offset(-11.0f);
  64. make.height.mas_equalTo(22.0f);
  65. make.centerY.mas_equalTo(headView.mas_centerY);
  66. }];
  67. [self.view addSubview:self.collectionView];
  68. [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
  69. make.left.mas_equalTo(self.view.mas_left).offset(15);
  70. make.right.mas_equalTo(self.view.mas_right).offset(-15);
  71. make.top.mas_equalTo(headView.mas_bottom);
  72. make.bottom.mas_equalTo(self.bottomView.mas_top);
  73. }];
  74. }
  75. - (void)requestInstrumentMessage {
  76. [LOADING_MANAGER showHUD];
  77. [KSNetworkingManager querySubjectAllRequest:KS_GET success:^(NSDictionary * _Nonnull dic) {
  78. [LOADING_MANAGER removeHUD];
  79. if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
  80. [self evaluateSource:[dic ks_arrayValueForKey:@"data"]];
  81. }
  82. else {
  83. [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
  84. }
  85. } faliure:^(NSError * _Nonnull error) {
  86. [LOADING_MANAGER removeHUD];
  87. }];
  88. }
  89. - (void)evaluateSource:(NSArray *)sourceArray {
  90. @autoreleasepool {
  91. NSMutableArray *valueArray = [sourceArray mutableCopy];
  92. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  93. NSMutableArray *parentNodeArray = [NSMutableArray array];
  94. NSMutableArray *instrumentArray = [NSMutableArray array];
  95. for (NSInteger i = 0; i < valueArray.count; i++) {
  96. NSMutableDictionary *parentNodeDic = [NSMutableDictionary dictionary];
  97. NSDictionary *parm = valueArray[i];
  98. [parentNodeDic setValue:[parm ks_stringValueForKey:@"id"] forKey:@"subjectId"];
  99. [parentNodeDic setValue:[parm ks_stringValueForKey:@"name"] forKey:@"subjectName"];
  100. NSArray *subjects = [parm ks_arrayValueForKey:@"subjects"];
  101. if (subjects.count > 0) {
  102. // 添加父节点分类
  103. [parentNodeArray addObject:parentNodeDic];
  104. NSMutableArray *subjectModelArray = [NSMutableArray array];
  105. for (NSDictionary *dic in subjects) {
  106. InstrumentMessageModel *model = [[InstrumentMessageModel alloc] initWithDictionary:dic];
  107. if (self.preChooseArray.count && [self judgePreChooseInstrument:model.internalBaseClassIdentifier]) {
  108. model.isChoose = YES;
  109. [self.chooseArray addObject:model];
  110. }
  111. [subjectModelArray addObject:model];
  112. }
  113. [instrumentArray addObject:subjectModelArray];
  114. }
  115. }
  116. self.parentArray = [NSMutableArray arrayWithArray:parentNodeArray];
  117. self.instrumentArray = [NSMutableArray arrayWithArray:instrumentArray];
  118. dispatch_main_async_safe(^{
  119. // 刷新
  120. [self refreshView];
  121. });
  122. });
  123. };
  124. }
  125. - (BOOL)judgePreChooseInstrument:(NSString *)instrumentId {
  126. BOOL contain = NO;
  127. for (NSDictionary *parm in self.preChooseArray) {
  128. if ([[parm valueForKey:@"subjectId"] isEqualToString:instrumentId]) {
  129. contain = YES;
  130. break;
  131. }
  132. }
  133. return contain;
  134. }
  135. - (void)refreshView {
  136. [self.collectionView reloadData];
  137. }
  138. #pragma mark ----- collection view data source
  139. - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
  140. return self.parentArray.count;
  141. }
  142. - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
  143. NSMutableArray *instrumentArray = self.instrumentArray[section];
  144. return instrumentArray.count;
  145. }
  146. - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  147. NSMutableArray *instrumentArray = self.instrumentArray[indexPath.section];
  148. InstrumentMessageModel *model = instrumentArray[indexPath.item];
  149. InstrumentChooseCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"InstrumentChooseCell" forIndexPath:indexPath];
  150. [cell configCellWithModel:model];
  151. return cell;
  152. }
  153. - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
  154. NSMutableArray *instrumentArray = self.instrumentArray[indexPath.section];
  155. InstrumentMessageModel *model = instrumentArray[indexPath.item];
  156. model.isChoose = !model.isChoose;
  157. [self countMessageWithModel:model indexPath:indexPath];
  158. }
  159. - (void)countMessageWithModel:(InstrumentMessageModel *)model indexPath:(NSIndexPath *)indexPath {
  160. if (self.isSingleChoose) { // 单选
  161. if (model.isChoose) {
  162. // 取消上一个选中
  163. if (self.chooseModel) {
  164. self.chooseModel.isChoose = NO;
  165. [self.collectionView reloadItemsAtIndexPaths:@[indexPath,self.chooseIndexPath]];
  166. }
  167. self.chooseModel = model;
  168. self.chooseIndexPath = indexPath;
  169. }
  170. else {
  171. self.chooseModel = nil;
  172. self.chooseIndexPath = nil;
  173. }
  174. if (self.chooseIndexPath) {
  175. [self.collectionView reloadItemsAtIndexPaths:@[indexPath,self.chooseIndexPath]];
  176. }
  177. else {
  178. [self.collectionView reloadItemsAtIndexPaths:@[indexPath]];
  179. }
  180. }
  181. else { // 多选
  182. if (model.isChoose) {
  183. if (![self judgeContainModel:model]) {
  184. if (self.chooseArray.count == 5) {
  185. [LOADING_MANAGER MBShowAUTOHidingInWindow:@"最多只能选择5个乐器"];
  186. model.isChoose = NO;
  187. return;
  188. }
  189. [self.chooseArray addObject:model];
  190. }
  191. }
  192. else {
  193. if ([self judgeContainModel:model]) {
  194. [self removeWithInstrumentId:model.internalBaseClassIdentifier];
  195. }
  196. }
  197. [self.collectionView reloadItemsAtIndexPaths:@[indexPath]];
  198. }
  199. }
  200. - (BOOL)judgeContainModel:(InstrumentMessageModel *)model {
  201. BOOL contain = NO;
  202. for (InstrumentMessageModel *chooseModel in self.chooseArray) {
  203. if ([chooseModel.internalBaseClassIdentifier isEqualToString:model.internalBaseClassIdentifier]) {
  204. contain = YES;
  205. break;
  206. }
  207. }
  208. return contain;
  209. }
  210. - (void)removeWithInstrumentId:(NSString *)instrumentId {
  211. for (InstrumentMessageModel *chooseModel in self.chooseArray) {
  212. if ([chooseModel.internalBaseClassIdentifier isEqualToString:instrumentId]) {
  213. [self.chooseArray removeObject:chooseModel];
  214. break;
  215. }
  216. }
  217. }
  218. - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
  219. NSDictionary *parm = self.parentArray[indexPath.section];
  220. NSString *subjectName = [parm ks_stringValueForKey:@"subjectName"];
  221. InstrumentHeaderView *headView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"InstrumentHeaderView" forIndexPath:indexPath];
  222. [headView evaluateWithMessage:subjectName];
  223. return headView;
  224. }
  225. #pragma mark ------ lazying
  226. - (NSMutableArray *)chooseArray {
  227. if (!_chooseArray) {
  228. _chooseArray = [NSMutableArray array];
  229. }
  230. return _chooseArray;
  231. }
  232. - (UICollectionView *)collectionView {
  233. if (!_collectionView) {
  234. UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
  235. CGFloat width = (NSInteger)((KPortraitWidth - 15 * 2 - (INSTRUMENT_ROWCOUNT-1)* 10) / INSTRUMENT_ROWCOUNT);
  236. CGFloat height = width;
  237. layout.itemSize = CGSizeMake(width, height);
  238. layout.headerReferenceSize = CGSizeMake(kScreen_Width - 30, 40);
  239. _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
  240. _collectionView.backgroundColor = [UIColor clearColor];
  241. _collectionView.delegate = self;
  242. _collectionView.dataSource = self;
  243. _collectionView.showsVerticalScrollIndicator = NO;
  244. _collectionView.showsHorizontalScrollIndicator = NO;
  245. [_collectionView registerNib:[UINib nibWithNibName:@"InstrumentChooseCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:@"InstrumentChooseCell"];
  246. [_collectionView registerNib:[UINib nibWithNibName:@"InstrumentHeaderView" bundle:[NSBundle mainBundle]] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"InstrumentHeaderView"];
  247. }
  248. return _collectionView;
  249. }
  250. - (InstrumentChooseBottonView *)bottomView {
  251. if (!_bottomView) {
  252. _bottomView = [InstrumentChooseBottonView shareInstance];
  253. MJWeakSelf;
  254. [_bottomView sureCallback:^{
  255. [weakSelf chooseInstrumentAction];
  256. }];
  257. }
  258. return _bottomView;
  259. }
  260. - (void)chooseInstrumentAction {
  261. if (self.isSingleChoose) {
  262. if (self.chooseModel == nil) {
  263. [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请选择乐器"];
  264. return;
  265. }
  266. NSMutableArray *instrumentArray = [NSMutableArray array];
  267. NSMutableDictionary *parm = [NSMutableDictionary dictionary];
  268. [parm setValue:self.chooseModel.name forKey:@"subjectName"];
  269. [parm setValue:self.chooseModel.internalBaseClassIdentifier forKey:@"subjectId"];
  270. [instrumentArray addObject:parm];
  271. if (self.callback) {
  272. self.callback(instrumentArray);
  273. }
  274. }
  275. else {
  276. if (self.chooseArray.count == 0) {
  277. [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请选择可教授乐器"];
  278. return;
  279. }
  280. NSMutableArray *instrumentArray = [NSMutableArray array];
  281. for (InstrumentMessageModel *model in self.chooseArray) {
  282. NSMutableDictionary *parm = [NSMutableDictionary dictionary];
  283. [parm setValue:model.name forKey:@"subjectName"];
  284. [parm setValue:model.internalBaseClassIdentifier forKey:@"subjectId"];
  285. [instrumentArray addObject:parm];
  286. }
  287. if (self.callback) {
  288. self.callback(instrumentArray);
  289. }
  290. }
  291. [self backAction];
  292. }
  293. /*
  294. #pragma mark - Navigation
  295. // In a storyboard-based application, you will often want to do a little preparation before navigation
  296. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  297. // Get the new view controller using [segue destinationViewController].
  298. // Pass the selected object to the new view controller.
  299. }
  300. */
  301. @end