YMPickerPopupView.m 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. //
  2. // YMPickerPopupView.m
  3. // MSYOUPAI
  4. //
  5. // Created by YoMi on 2024/2/11.
  6. // Copyright © 2024 MS. All rights reserved.
  7. //
  8. #import "YMPickerPopupView.h"
  9. @interface YMPickerPopupView ()<UIPickerViewDelegate,UIPickerViewDataSource>
  10. /** 选择器VM*/
  11. @property (nonatomic, strong) YMPickerViewModel *viewModel;
  12. /** 标题标签*/
  13. @property (nonatomic, strong) UILabel *titleLb;
  14. /** 取消按钮*/
  15. @property (nonatomic, strong) UIButton *cancelBtn;
  16. /** 确认按钮*/
  17. @property (nonatomic, strong) UIButton *confirmBtn;
  18. /** 选择器*/
  19. @property (nonatomic, strong) UIPickerView *pickerView;
  20. /** 当前选中数据*/
  21. @property (nonatomic, strong) NSArray <NSMutableDictionary*>*currentSelectedDataArray;
  22. @end
  23. @implementation YMPickerPopupView
  24. - (void)ym_setupViews{
  25. self.frame = CGRectMake(0, 0, kFrameWidth, 250);
  26. self.backgroundColor = HexColorFromRGB(0xFFFFFF);
  27. self.titleText = @"请选择选项";
  28. self.titleColor = HexColorFromRGB(0x000000);
  29. self.titleFont = LCFont(13);
  30. self.cancelBgColor = [UIColor clearColor];
  31. self.confirmBgColor = [UIColor clearColor];
  32. self.cancelTitleColor = HexColorFromRGB(0x333333);
  33. self.confirmTitleColor = HexColorFromRGB(0x333333);
  34. self.cancelFont = LCFont(14);
  35. self.confirmFont = LCFont(14);
  36. self.cancelTitle = @"取消";
  37. self.confirmTitle = @"确定";
  38. self.cancelRadius = 10;
  39. self.confirmRadius = 10;
  40. self.cancelBorderColor = [UIColor clearColor];
  41. self.confirmBorderColor = [UIColor clearColor];
  42. self.cancelBorderWidth = 0;
  43. self.confirmBorderWidth = 0;
  44. [self addSubview:self.cancelBtn];
  45. [self addSubview:self.titleLb];
  46. [self addSubview:self.confirmBtn];
  47. [self addSubview:self.pickerView];
  48. [self setNeedsUpdateConstraints];
  49. [self updateConstraintsIfNeeded];
  50. }
  51. - (void)updateConstraints{
  52. [self.cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  53. make.top.equalTo(self).offset(adapt(10));
  54. make.left.equalTo(self).offset(adapt(10));
  55. make.width.mas_equalTo(adapt(60));
  56. make.height.mas_equalTo(adapt(30));
  57. }];
  58. [self.titleLb mas_makeConstraints:^(MASConstraintMaker *make) {
  59. make.top.equalTo(self).offset(adapt(10));
  60. make.left.equalTo(self.cancelBtn.mas_right).offset(adapt(10));
  61. make.right.equalTo(self.confirmBtn.mas_left).offset(adapt(-10));
  62. make.height.mas_equalTo(adapt(30));
  63. }];
  64. [self.confirmBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  65. make.top.equalTo(self).offset(adapt(10));
  66. make.right.equalTo(self).offset(adapt(-10));
  67. make.width.mas_equalTo(adapt(60));
  68. make.height.mas_equalTo(adapt(30));
  69. }];
  70. [self.pickerView mas_makeConstraints:^(MASConstraintMaker *make) {
  71. make.top.equalTo(self.titleLb.mas_bottom);
  72. make.left.equalTo(self);
  73. make.right.equalTo(self);
  74. make.bottom.equalTo(self).offset(adapt(-15));
  75. }];
  76. [super updateConstraints];
  77. }
  78. - (void)ym_bindViewModel:(YMPickerViewModel *)viewModel{
  79. if (!viewModel) {
  80. return;
  81. }
  82. _viewModel = viewModel;
  83. [self.pickerView reloadAllComponents];
  84. for (int i = 0; i < self.viewModel.componentDataSource.count; i++) {
  85. //每次显示picker的时候都选中第一行
  86. [self.pickerView selectRow:0 inComponent:i animated:YES];
  87. //实现默认选中第一行的点击方法,将第一行的title传给控制器
  88. [self pickerView:self.pickerView didSelectRow:0 inComponent:i];
  89. }
  90. }
  91. //返回UIPickerView中Component列的宽度
  92. - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component{
  93. return self.viewModel.componentDataSource.count <= 1 ? self.frame.size.width : self.viewModel.componentDataSource[component].componentWidth;
  94. }
  95. //返回UIPickerView中Component列中每行的高度
  96. - (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component{
  97. return 50;
  98. }
  99. //该方法返回值决定该控件包含多少列
  100. - (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView{
  101. return self.viewModel.componentDataSource.count;
  102. }
  103. //该方法的返回值决定该控件指定列包含多少个列表项
  104. - (NSInteger)pickerView:(UIPickerView *)pickerView
  105. numberOfRowsInComponent:(NSInteger)component{
  106. return self.viewModel.componentDataSource[component].rowDataSource.count;
  107. }
  108. // UIPickerView中指定列和列表项上显示的标题
  109. - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:
  110. (NSInteger)row forComponent:(NSInteger)component{
  111. return self.viewModel.componentDataSource[component].rowDataSource[row].rowName;
  112. }
  113. // 当用户选中UIPickerViewDataSource中指定列和列表项时激发该方法
  114. - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
  115. self.viewModel.componentDataSource[component].currentSelectedSectionIndex = component;
  116. self.viewModel.componentDataSource[component].currentSelectedRowIndex = row;
  117. self.viewModel.componentDataSource[component].currentSelectedValue = self.viewModel.componentDataSource[component].rowDataSource[row].rowName;
  118. }
  119. - (void)setTitleText:(NSString *)titleText{
  120. _titleText = titleText;
  121. self.titleLb.text = titleText;
  122. }
  123. - (void)setCancelBgColor:(UIColor *)cancelBgColor{
  124. _cancelBgColor = cancelBgColor;
  125. _cancelBtn.backgroundColor = cancelBgColor;
  126. }
  127. - (void)setConfirmBgColor:(UIColor *)confirmBgColor{
  128. _confirmBgColor = confirmBgColor;
  129. self.confirmBtn.backgroundColor = confirmBgColor;
  130. }
  131. - (void)setCancelTitleColor:(UIColor *)cancelTitleColor{
  132. _cancelTitleColor = cancelTitleColor;
  133. [self.cancelBtn setTitleColor:cancelTitleColor forState:UIControlStateNormal];
  134. }
  135. - (void)setConfirmTitleColor:(UIColor *)confirmTitleColor{
  136. _confirmTitleColor = confirmTitleColor;
  137. [self.confirmBtn setTitleColor:confirmTitleColor forState:UIControlStateNormal];
  138. }
  139. - (void)setCancelFont:(UIFont *)cancelFont{
  140. _cancelFont = cancelFont;
  141. self.cancelBtn.titleLabel.font = cancelFont;
  142. }
  143. - (void)setConfirmFont:(UIFont *)confirmFont{
  144. _confirmFont = confirmFont;
  145. self.confirmBtn.titleLabel.font = confirmFont;
  146. }
  147. - (void)setCancelTitle:(NSString *)cancelTitle{
  148. _cancelTitle = cancelTitle;
  149. [self.cancelBtn setTitle:cancelTitle forState:UIControlStateNormal];
  150. }
  151. - (void)setConfirmTitle:(NSString *)confirmTitle{
  152. _confirmTitle = confirmTitle;
  153. [self.confirmBtn setTitle:confirmTitle forState:UIControlStateNormal];
  154. }
  155. - (void)setCancelRadius:(CGFloat)cancelRadius{
  156. _cancelRadius = cancelRadius;
  157. self.cancelBtn.layer.cornerRadius = cancelRadius;
  158. }
  159. - (void)setConfirmRadius:(CGFloat)confirmRadius{
  160. _confirmRadius = confirmRadius;
  161. self.confirmBtn.layer.cornerRadius = confirmRadius;
  162. }
  163. - (void)setCancelBorderColor:(UIColor *)cancelBorderColor{
  164. _cancelBorderColor = cancelBorderColor;
  165. self.cancelBtn.layer.borderColor = cancelBorderColor.CGColor;
  166. }
  167. - (void)setConfirmBorderColor:(UIColor *)confirmBorderColor{
  168. _confirmBorderColor = confirmBorderColor;
  169. self.confirmBtn.layer.borderColor = confirmBorderColor.CGColor;
  170. }
  171. - (void)setCancelBorderWidth:(CGFloat)cancelBorderWidth{
  172. _cancelBorderWidth = cancelBorderWidth;
  173. self.cancelBtn.layer.borderWidth = cancelBorderWidth;
  174. }
  175. - (void)setConfirmBorderWidth:(CGFloat)confirmBorderWidth{
  176. _confirmBorderWidth = confirmBorderWidth;
  177. self.confirmBtn.layer.borderWidth = confirmBorderWidth;
  178. }
  179. - (UILabel *)titleLb{
  180. if (!_titleLb) {
  181. _titleLb = [[UILabel alloc]init];
  182. _titleLb.textAlignment = NSTextAlignmentCenter;
  183. _titleLb.textColor = self.titleColor;
  184. _titleLb.font = self.titleFont;
  185. _titleLb.text = self.titleText;
  186. }
  187. return _titleLb;
  188. }
  189. - (UIButton *)cancelBtn {
  190. if(!_cancelBtn){
  191. _cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  192. _cancelBtn.backgroundColor = self.cancelBgColor;
  193. _cancelBtn.titleLabel.font = self.cancelFont;
  194. [_cancelBtn setTitleColor:self.cancelTitleColor forState:UIControlStateNormal];
  195. [_cancelBtn setTitle:self.cancelTitle forState:UIControlStateNormal];
  196. _cancelBtn.layer.cornerRadius = self.cancelRadius;
  197. _cancelBtn.layer.borderWidth = self.cancelBorderWidth;
  198. _cancelBtn.layer.borderColor = self.cancelBorderColor.CGColor;
  199. WS(weakSelf)
  200. [[[_cancelBtn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(id x) {
  201. if (weakSelf.buttonBlock) {
  202. weakSelf.buttonBlock(NO, @[]);
  203. }
  204. }];
  205. }
  206. return _cancelBtn;
  207. }
  208. - (UIButton *)confirmBtn {
  209. if(!_confirmBtn){
  210. _confirmBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  211. _confirmBtn.backgroundColor = self.confirmBgColor;
  212. _confirmBtn.titleLabel.font = self.confirmFont;
  213. [_confirmBtn setTitleColor:self.confirmTitleColor forState:UIControlStateNormal];
  214. [_confirmBtn setTitle:self.confirmTitle forState:UIControlStateNormal];
  215. _confirmBtn.layer.cornerRadius = self.confirmRadius;
  216. _confirmBtn.layer.borderWidth = self.confirmBorderWidth;
  217. _confirmBtn.layer.borderColor = self.confirmBorderColor.CGColor;
  218. WS(weakSelf)
  219. [[[_confirmBtn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(id x) {
  220. if (weakSelf.buttonBlock) {
  221. weakSelf.currentSelectedDataArray = [weakSelf.viewModel.componentDataSource.rac_sequence map:^(YMPickerComponentViewModel *_Nullable componentModel) {
  222. NSMutableDictionary *mDic = [NSMutableDictionary dictionary];
  223. [mDic setObject:componentModel.componentName forKey:@"componentName"];
  224. [mDic setObject:@(componentModel.currentSelectedSectionIndex) forKey:@"currentSelectedSectionIndex"];
  225. [mDic setObject:@(componentModel.currentSelectedRowIndex) forKey:@"currentSelectedRowIndex"];
  226. [mDic setObject:componentModel.currentSelectedValue forKey:@"currentSelectedValue"];
  227. return mDic;
  228. }].array;
  229. weakSelf.buttonBlock(YES, weakSelf.currentSelectedDataArray);
  230. }
  231. }];
  232. }
  233. return _confirmBtn;
  234. }
  235. - (UIPickerView *)pickerView{
  236. if (!_pickerView) {
  237. _pickerView = [[UIPickerView alloc]init];
  238. _pickerView.delegate = self;
  239. _pickerView.dataSource = self;
  240. _pickerView.showsSelectionIndicator = YES;
  241. }
  242. return _pickerView;
  243. }
  244. - (NSArray <NSMutableDictionary*>*)currentSelectedDataArray{
  245. if (!_currentSelectedDataArray) {
  246. _currentSelectedDataArray = [NSArray array];
  247. }
  248. return _currentSelectedDataArray;
  249. }
  250. @end
  251. @interface YMPickerViewModel ()
  252. /** 行列表 */
  253. @property (nonatomic, strong, readwrite) NSArray <YMPickerComponentViewModel*>*componentDataSource;
  254. @end
  255. @implementation YMPickerViewModel
  256. - (void)ym_initialize{
  257. [super ym_initialize];
  258. if([[self.params allKeys] containsObject:@"componentDataSource"]){
  259. self.componentDataSource = [[self.params arrayValueForKey:@"componentDataSource" defaultValue:@[]].rac_sequence map:^(id _Nullable componentModel) {
  260. YMPickerComponentViewModel *viewModel = [[YMPickerComponentViewModel alloc]initWithParams:componentModel];
  261. return viewModel;
  262. }].array;
  263. }
  264. }
  265. @end
  266. @interface YMPickerComponentViewModel ()
  267. /** 分组Id */
  268. @property (nonatomic, copy, readwrite) NSString *componentId;
  269. /** 分组名 */
  270. @property (nonatomic, copy, readwrite) NSString *componentName;
  271. /** 分组宽度 */
  272. @property (nonatomic, assign, readwrite) CGFloat componentWidth;
  273. /** 行列表 */
  274. @property (nonatomic, strong, readwrite) NSArray *rowDataSource;
  275. @end
  276. @implementation YMPickerComponentViewModel
  277. - (void)ym_initialize{
  278. [super ym_initialize];
  279. if([[self.params allKeys] containsObject:@"componentId"]){
  280. self.componentId = [self.params stringValueForKey:@"componentId" defaultValue:@""];
  281. }
  282. if([[self.params allKeys] containsObject:@"componentName"]){
  283. self.componentName = [self.params stringValueForKey:@"componentName" defaultValue:@""];
  284. }
  285. self.componentWidth = [self.params floatValueForKey:@"componentWidth" defaultValue:100.0f];
  286. if([[self.params allKeys] containsObject:@"rowDataSource"]){
  287. self.rowDataSource = [[self.params arrayValueForKey:@"rowDataSource" defaultValue:@[]].rac_sequence map:^(id _Nullable rowModel) {
  288. YMPickerRowViewModel *viewModel = [[YMPickerRowViewModel alloc]initWithParams:rowModel];
  289. return viewModel;
  290. }].array;
  291. }
  292. }
  293. @end
  294. @interface YMPickerRowViewModel ()
  295. /** 分组Id */
  296. @property (nonatomic, copy, readwrite) NSString *componentId;
  297. /** 行Id */
  298. @property (nonatomic, copy, readwrite) NSString *rowId;
  299. /** 标题名 */
  300. @property (nonatomic, copy, readwrite) NSString *rowName;
  301. @end
  302. @implementation YMPickerRowViewModel
  303. - (void)ym_initialize{
  304. [super ym_initialize];
  305. if([[self.params allKeys] containsObject:@"componentId"]){
  306. self.componentId = [self.params stringValueForKey:@"componentId" defaultValue:@""];
  307. }
  308. if([[self.params allKeys] containsObject:@"rowId"]){
  309. self.rowId = [self.params stringValueForKey:@"rowId" defaultValue:@""];
  310. }
  311. if([[self.params allKeys] containsObject:@"rowName"]){
  312. self.rowName = [self.params stringValueForKey:@"rowName" defaultValue:@""];
  313. }
  314. }
  315. @end